欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java線程創(chuàng)建的四種方式總結(jié)

 更新時間:2021年09月14日 09:31:01   作者:威斯布魯克.猩猩  
這篇文章主要介紹了Java線程創(chuàng)建的四種方式,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

多線程的創(chuàng)建,方式一:繼承于Thread類

1.創(chuàng)建一個繼承于Thread類的子類

2.重寫Thread類的run()--->將此線程執(zhí)行的操作聲明在run()中

3.創(chuàng)建Thread類的子類的對象

4.通過此對象調(diào)用start():

start()方法的兩個作用:

A.啟動當(dāng)前線程

B.調(diào)用當(dāng)前線程的run()

創(chuàng)建過程中的兩個問題:

問題一:我們不能通過直接調(diào)用run()的方式啟動線程

問題二:在啟動一個線程,遍歷偶數(shù),不可以讓已經(jīng)start()的線程去執(zhí)行,會報異常;正確的方式是重新創(chuàng)建一個線程的對象。

//1.創(chuàng)建一個繼承于Thread類的子類
class MyThread extends Thread{
    //2.重寫Thread類的run()
    @Override
    public void run() {//第二個線程
       for(int i = 0;i < 10;i++){
           if(i % 2 == 0){
               System.out.println(i);
           }
       }
    }
}
public class ThreadTest {
    public static void main(String[] args) {//主線程
        //3.創(chuàng)建Thread類的子類的對象
        MyThread t1 = new MyThread();
        //4.通過此對象調(diào)用start()
        t1.start();
        //問題一:不能通過直接調(diào)用run()的方式啟動線程
//        t1.run();//錯誤的
        //問題二:再啟動一個線程:我們需要再創(chuàng)建 一個對象
        //t1.start();//錯誤的
        MyThread t2 = new MyThread();
        t2.start();
 
        for(int i = 0;i < 10;i++){
            if(i % 2 != 0){
                System.out.println(i + "****main()******");
            }
        }
    }
}

此代碼在主線程內(nèi)輸出奇數(shù),在另一個線程里輸出偶數(shù),則輸出結(jié)果應(yīng)該是兩個輸出結(jié)果是交互的。

1****main()******
3****main()******
5****main()******
7****main()******
0
2
4
6
8
9****main()******

class Window extends Thread{//創(chuàng)建三個窗口賣票, 總票數(shù)為100張,使用繼承于Thread類的方式
    private static int ticket = 100;//三個窗口共享:聲明為static
    @Override
    public void run() {
        while(true){
            if(ticket > 0){
                System.out.println(getName() + ":賣票,票號為:" + ticket);
                ticket--;
            }else{
                break;
            }
        }
    }
}
public class WindowTest2 {
    public static void main(String[] args) {
        Window t1 = new Window();
        Window t2 = new Window();
        Window t3 = new Window();
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}
public class ThreadDemo {
    public static void main(String[] args) {
//        MyThread1 m1 = new MyThread1();
//        MyThread2 m2 = new MyThread2();
//        m1.start();
//        m2.start();
        //由于造的類只創(chuàng)建過一次對象,后面就不用了,可以考慮使用匿名類的方式
        //創(chuàng)建Thread類的匿名子類的方式
        new Thread(){
            @Override
            public void run() {
                for(int i = 0;i < 100;i++){
                    if(i % 2 == 0){
                        System.out.println(i);
                    }
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                for(int i = 0;i < 100;i++){
                    if(i % 2 != 0){
                        System.out.println(i);
                    }
                }
            }
        }.start();
    }
}
class MyThread1 extends Thread{
    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            if(i % 2 == 0){
                System.out.println(i);
            }
        }
    }
}
class MyThread2 extends Thread{
    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            if(i % 2 != 0){
                System.out.println(i);
            }
        }
    }
}

創(chuàng)建多線程的方式二:實現(xiàn)Runnable接口

  • 創(chuàng)建一個實現(xiàn)了Runnable接口的類
  • 實現(xiàn)類去實現(xiàn)Runnable中的抽象方法:run()
  • 創(chuàng)建實現(xiàn)類的對象
  • 將此對象作為參數(shù)傳遞到Thread類的構(gòu)造器中,創(chuàng)建Thread類的對象
  • 通過Thread類的對象調(diào)用start()
class MThread implements Runnable{
    //2.實現(xiàn)類去實現(xiàn)Runnable中的抽象方法:run()
    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            if (i % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}
public class ThreadTest1 {
    public static void main(String[] args) {
        //3.創(chuàng)建實現(xiàn)類的對象
        MThread mThread = new MThread();
        //4.將此對象作為參數(shù)傳遞到Thread類的構(gòu)造器中,創(chuàng)建Thread類的對象
        Thread t1 = new Thread(mThread);
        t1.setName("線程1");
        //5.通過Thread類的對象調(diào)用start():A.啟動線程B.調(diào)用當(dāng)前線程的run()-->調(diào)用了Runnable類型的target
        t1.start();
        //再啟動一個線程,遍歷100以內(nèi)的偶數(shù)//只需重新實現(xiàn)步驟4,5即可
        Thread t2 = new Thread(mThread);
        t2.setName("線程2");
        t2.start();
    }
}
class window1 implements Runnable{//創(chuàng)建三個窗口賣票, 總票數(shù)為100張,使用實現(xiàn)Runnable接口的方式
    private int ticket = 100;
    Object obj = new Object();
    @Override
    public void run() {
        while (true){
            if (ticket > 0) {
                System.out.println(Thread.currentThread().getName() + "賣票,票號為:" + ticket);
                ticket--;
            } else {
                break;
            }
        }
    }
}
public class WindowTest {
    public static void main(String[] args) {
        window1 w = new window1();//只造了一個對象,所以100張票共享
        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);
        t1.setName("線程1");
        t2.setName("線程2");
        t3.setName("線程3");
        t1.start();
        t2.start();
        t3.start();
    }
}

創(chuàng)建線程的方式三:實現(xiàn)Callable接口---JDK5.0新增

與使用Runnable相比,Callable功能更強大些

>相比run()方法,可以有返回值

>方法可以拋出異常

>支持泛型的返回值

>需要借助FutureTask類,比如獲取返回結(jié)果

Future接口

>可以對具體Runnable、Callable任務(wù)的執(zhí)行結(jié)果進行取消、查詢是否完成、獲取結(jié)果等。

>FutureTask是Futrue接口的唯一的實現(xiàn)類

>FutureTaskb同時實現(xiàn)了Runnable,Future接口。它既可以作為Runnable被線程執(zhí)行,又可以作為Future得到Callable的返回值

//1.創(chuàng)建一個實現(xiàn)Callable的實現(xiàn)類
class NumThread implements Callable{
    //2.實現(xiàn)call方法,將此線程需要執(zhí)行的操作聲明在call()中
    @Override
    public Object call() throws Exception {
        int sum = 0;
        for(int i = 1;i <= 100;i++){
            if(i % 2 == 0){
                System.out.println(i);
                sum += i;
            }
        }
        return sum;//sum是int,自動裝箱為Integer(Object的子類)
    }
}
public class ThreadNew {
    public static void main(String[] args) {
        //3.創(chuàng)建Callable接口實現(xiàn)類的對象
        NumThread numThread = new NumThread();
        //4.將此Callable接口實現(xiàn)類的對象作為參數(shù)傳遞到 FutureTask的構(gòu)造器中,創(chuàng)建FutureTask的對象
        FutureTask futureTask = new FutureTask(numThread);
        //5.將 FutureTask的對象作為參數(shù)傳遞到Thread類的構(gòu)造器中,創(chuàng)建Thread對象,并調(diào)用start()
        new Thread(futureTask).start();
        try {
            //獲取Callable中call()的返回值(不是必須的步驟)
            //get()返回值即為FutureTask構(gòu)造器參數(shù)Callable實現(xiàn)類重寫的call()的返回值。
            Object sum = futureTask.get();
            System.out.println("總和為:" + sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

創(chuàng)建線程的方式四:使用線程池--->JDK5.0新增

背景:經(jīng)常創(chuàng)建和銷毀、使用量特別大的資源,比如并發(fā)情況下的線程,對性能影響很大。

思路:提前創(chuàng)建好多個線程,放入線程池中,使用時直接獲取,使用完放回池中??梢员苊忸l繁創(chuàng)建銷毀、實現(xiàn)重復(fù)利用。類似生活中的公共交通工具。

好處:>提高響應(yīng)速度(減少了創(chuàng)建新線程的時間)

>降低資源消耗(重復(fù)利用線程池中線程,不需要每次都創(chuàng)建)

>便于線程管理:A.corePoolSize:核心池的大小 B.maximumPoolSize:最大線程數(shù) C.keepAliveTime:線程沒有任務(wù)時最多保持多長時間后會終止

class NumberThread implements Runnable{
 
    @Override
    public void run() {
        for(int i = 0;i <= 100;i++){
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}
class NumberThread1 implements Runnable{
    @Override
    public void run() {
        for(int i = 0;i <= 100;i++){
            if(i % 2 != 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}
public class ThreadPool {
    public static void main(String[] args) {
        //1.提供指定線程數(shù)量的線程池
        ExecutorService service = Executors.newFixedThreadPool(10);
        ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
        //設(shè)置線程池的屬性
//        System.out.println(service.getClass());
//        service1.setCorePoolSize(15);
//        service1.setKeepAliveTime();
        //2.執(zhí)行指定的線程操作。需要提供實現(xiàn)Runnable 接口或Callable接口實現(xiàn)類的對象
        service.execute(new NumberThread());//適用于Runnable
        service.execute(new NumberThread1());//適用于Runnable
//        service.submit(Callable callable);//適用于Callable
        //3.關(guān)閉連接池
        service.shutdown();
    }
}

比較創(chuàng)建線程的兩種方式:

開發(fā)中:優(yōu)先選擇:實現(xiàn)Runnable接口的方式
原因:1.實現(xiàn)的方式?jīng)]有類的單繼承性的局限性
2.實現(xiàn)的方式更適合來處理多個線程有共享數(shù)據(jù)的情況。
系:public class Thread implements Runnable
相同點:兩種方式都需要重寫run(),將線程要執(zhí)行的邏輯聲明在run()中

程序(program)是為完成特定任務(wù)、用某種語言編寫的一組指令的集合。即指一段靜態(tài)的代碼,靜態(tài)對象。

進程(process)是程序的一次執(zhí)行過程,或是正在運行的一個程序。是一個動態(tài)的過程:有它自身的產(chǎn)生、存在和消亡的過程。---生命周期

線程(thread),進程可進一步細(xì)化為線程,是一個程序內(nèi)部的一條執(zhí)行路徑。

線程作為調(diào)度和執(zhí)行的單位,每個線程擁有獨立的運行棧和計數(shù)器,每個進程擁有獨立的方法區(qū)和堆;意味著,多個線程共享一個方法區(qū)和堆。而共享的就可以優(yōu)化,同時,共享的也會帶來安全隱患,這就需要我們解決線程安全問題

背景:以單核CPU為例,只使用單個線程先后完成多個任務(wù)(調(diào)用多個方法),肯定比用多個線程來完成用的時間更短,為何仍需使用多線程呢?

使用多線程的優(yōu)點:

1.提高應(yīng)用程序的響應(yīng)。對圖形化界面更有意義,可增強用戶體驗。

2.提高計算機系統(tǒng)CPU的利用率

3.改善程序結(jié)構(gòu)。將即長又復(fù)雜的線程分為多個線程,獨立運行,利于理解和修改

何時需要多線程

1.程序需要同時執(zhí)行兩個或多個任務(wù)。

2.程序需要實現(xiàn)一些需要等待的任務(wù)時,如用戶輸入、文件讀寫操作、網(wǎng)絡(luò)操作、搜索等。

3.需要一些后臺運行的程序時。

public class Sample{
    public void method1(String str){
        System.out.println(str);
    }
    public void method2(String str){
        method1(str);
    }
    public static void main(String[] args){
        Sample s = new Sample();
        s.method2("hello!");
    }
}

注意:此程序不是多線程!main方法中調(diào)用了method1,method1中又調(diào)用了method2;是一條執(zhí)行路徑,所以是單線程

測試Thread類的常用方法:

1.start():啟動當(dāng)前線程:調(diào)用當(dāng)前線程的run()
2.run():通常需要重寫Thread類中的此方法,將創(chuàng)建的線程要執(zhí)行的操作聲明在此方法中
3.currentThread():靜態(tài)方法,返回執(zhí)行當(dāng)前代碼的線程
4.getName():獲取當(dāng)前線程的名字
5.setName():設(shè)置當(dāng)前線程的名字
6.yield():釋放當(dāng)前CPU的執(zhí)行權(quán)(下一刻CPU執(zhí)行的線程仍是隨機的)
>暫停當(dāng)前正在執(zhí)行的線程,把執(zhí)行機會讓給優(yōu)先級相同或更高的線程
>若隊列中沒有同優(yōu)先級的線程,忽略此方法
7.join():在線程a中調(diào)用線程b的join(),此時,線程a就進入阻塞狀態(tài)(停止執(zhí)行),直到線程b完全執(zhí)行完以后,線程b才結(jié)束阻塞狀態(tài)(開始執(zhí)行)。
8.sleep(long millitime):讓當(dāng)前線程"睡眠"指定的millitime毫秒。在指定的millitime毫秒時間內(nèi),當(dāng)前線程是阻塞狀態(tài)。會拋出InterruptedException異常
* 9.isAlive():判斷當(dāng)前線程是否存活

class HelloThread extends Thread{
    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            if(i % 2 != 0){
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":" +Thread.currentThread().getPriority() + ":" + i);
            }
        }
    }
    public HelloThread(String name){
        super(name);
    }
}
public class ThreadMethodTest {
    public static void main(String[] args) {
        HelloThread h1 = new HelloThread("Thread:1");//通過構(gòu)造器給線程命名,但前期是得在子類中提供一個構(gòu)造器
//        h1.setName("線程一");
        //設(shè)置分線程的優(yōu)先級
        h1.setPriority(Thread.MAX_PRIORITY);
        h1.start();
        //給主線程命名
        Thread.currentThread().setName("主線程");
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
        for(int i = 0;i < 100;i++){
            if(i % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ":" + Thread.currentThread().getPriority() + ":" + i);
            }
//            if(i == 20){
//                try {
//                    h1.join();//join()的測試
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
        }
    }
}

線程的優(yōu)先級:

1.MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5--->默認(rèn)優(yōu)先級
2.如何獲取和設(shè)置當(dāng)前線程的優(yōu)先級:
getPriority():獲取線程的優(yōu)先級
setPriority(int p):設(shè)置線程的優(yōu)先級
說明:高優(yōu)先級的線程要搶占低優(yōu)先級線程CPU的執(zhí)行權(quán),但是只是從概率上講,高優(yōu)先級的線程高概率的情況下,不一定被執(zhí)行,并不意味著只有當(dāng)高優(yōu)先級的線程執(zhí)行完畢后,低優(yōu)先級的線程才執(zhí)行。

到此這篇關(guān)于Java線程創(chuàng)建的四種方式總結(jié)的文章就介紹到這了,更多相關(guān)Java 線程創(chuàng)建內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java?Collections工具類中常用算法解析

    Java?Collections工具類中常用算法解析

    在軟件開發(fā)中,算法是非常重要的一部分,它們可以提供高效的數(shù)據(jù)處理和操作,這篇文章主要為大家介紹了Collections?工具類集合框架中常用算法,感興趣的可以了解一下
    2023-06-06
  • Java的項目構(gòu)建工具Maven的配置和使用教程

    Java的項目構(gòu)建工具Maven的配置和使用教程

    Maven是Java世界中的項目管理和構(gòu)建自動化工具,基于POM項目對象模型的思想,下面我們就具體來看一下具體的Java的項目構(gòu)建工具Maven的配置和使用教程:
    2016-05-05
  • Java中static作用詳解

    Java中static作用詳解

    這篇文章主要介紹了Java中static作用,static表示“全局”或者“靜態(tài)”的意思,用來修飾成員變量和成員方法,也可以形成靜態(tài)static代碼塊,需要的朋友可以參考下
    2015-09-09
  • JAVA設(shè)計模式---單例模式你知道嗎

    JAVA設(shè)計模式---單例模式你知道嗎

    這篇文章主要給大家介紹了關(guān)于Java單例模式,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • Java 實戰(zhàn)項目錘煉之網(wǎng)上花店商城的實現(xiàn)流程

    Java 實戰(zhàn)項目錘煉之網(wǎng)上花店商城的實現(xiàn)流程

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+jsp+servlet+mysql+ajax實現(xiàn)一個網(wǎng)上花店商城系統(tǒng),大家可以在過程中查缺補漏,提升水平
    2021-11-11
  • 關(guān)于Spring?@Transactional事務(wù)傳播機制詳解

    關(guān)于Spring?@Transactional事務(wù)傳播機制詳解

    我們?nèi)粘9ぷ髦袠O少使用事務(wù)傳播級別,單純只是使用事務(wù)和rollbackfor拋出異常來解決事務(wù)問題,但其實我們很多時候使用的是不正確的,或者說會造成事務(wù)粒度過大,本文詳解一下事務(wù)傳播級別,也讓自己更好地處理事務(wù)問題,需要的朋友可以參考下
    2023-08-08
  • Java性能工具JMeter實現(xiàn)上傳與下載腳本編寫

    Java性能工具JMeter實現(xiàn)上傳與下載腳本編寫

    性能測試工作中,文件上傳也是經(jīng)常見的性能壓測場景之一,那么 JMeter 文件上傳下載腳本怎么做,本文詳細(xì)的來介紹一下,感興趣的可以了解一下
    2021-07-07
  • 如何將Java對象轉(zhuǎn)換成JSON

    如何將Java對象轉(zhuǎn)換成JSON

    這篇文章主要介紹了如何將Java對象轉(zhuǎn)換成JSON,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-11-11
  • 淺談Java中ArrayList的擴容機制

    淺談Java中ArrayList的擴容機制

    本文主要介紹了淺談Java中ArrayList的擴容機制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Spring Security @PreAuthorize注解分析

    Spring Security @PreAuthorize注解分析

    本教程介紹了如何使用 Spring 方法級安全和 @PreAuthorize 注解來保護 RestController 方法,通過這些步驟,您可以確保只有具有適當(dāng)角色或權(quán)限的用戶才能訪問特定的 REST API,感興趣的朋友跟隨小編一起看看吧
    2024-11-11

最新評論