最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中Thread類詳解及常用的方法

 更新時間:2022年05月06日 08:56:45   作者:富春山居_ZYY  
在java中談到線程,必然少不了Thread類,下面這篇文章主要給大家介紹了關(guān)于Java中Thread類及常用的方法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

一、Thread 的常見構(gòu)造方法

方法說明
Thread()創(chuàng)建線程對象
Thread(Runnable target)使用 Runnable 對象創(chuàng)建線程對象
Thread(String name)創(chuàng)建線程對象并命名
Thread(Runnable target,String name)使用 Runnable 對象創(chuàng)建線程對象并命名

關(guān)于前兩種方法,在之前的線程創(chuàng)建介紹中有使用到

線程創(chuàng)建根本上來講有兩種創(chuàng)建方法:

創(chuàng)建一個繼承自 Thread 類的子類,重寫 Thread 中的 run 方法,調(diào)用 start 方法創(chuàng)建一個實現(xiàn) Runnable 接口的類,重寫 Thread 中的 run 方法。創(chuàng)建 Thread 實例,將自己寫的實現(xiàn) Runnable 接口的類的實例設(shè)置進去,調(diào)用 start 方法

構(gòu)造方法三和四不過是在前面兩種構(gòu)造方法的基礎(chǔ)上多添加了一個給線程對象命名的參數(shù),方便程序員進行調(diào)試。

代碼(以構(gòu)造方法四為例):

public class func7 {
    public static void main(String[] args) {
        Thread thread = new Thread(() ->{
            while (true) {
                System.out.println("This is my Thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"myThread");
        //此處用 lambda 表達式代替 Runnable 實例,更加簡潔,添加了一個參數(shù)指定thread線程的名字
        thread.start();
        while (true) {
            System.out.println("my main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

程序員可以通過 JDK 自帶的jconsole工具來直觀查看這里創(chuàng)建的線程

步驟一:

運行程序后,找到自己的 jdk 路徑 -> bin ->jconsole.exe

步驟二:雙擊該 exe 文件。選擇本地進程,這里羅列著 Java 進程??梢钥匆娢覀兊某绦?func7 ,點擊它。在菜單欄選擇線程一欄

步驟三:查看線程信息

左側(cè)可以選擇需要被查看的線程,可以看見主線程 main和新創(chuàng)建的線程 myThread ,如果沒有重命名操作的話新創(chuàng)建的線程名就會叫 Thread-0,Thread-1 這樣的名字,不方便查看。

右側(cè)顯示了該線程的被讀取的那一瞬間的狀態(tài),堆棧跟蹤顯示的是代碼具體執(zhí)行的位置

二、Thread 的常見屬性

屬性方法
IDgetId()
名稱getName()
狀態(tài)getState()
優(yōu)先級getPriority()
是否為后臺線程isDaemon()
是否存活isAlive()
是否被中斷isInterrupted()

解釋:

  1. 線程的唯一標識就是線程 Id
  2. 名稱在上面的案例中有所體現(xiàn),為調(diào)試提供了便利
  3. 狀態(tài)表示線程當前所處的情況,上面的案例中,線程因為調(diào)用了 sleep 方法就進入了阻塞狀態(tài)
  4. 優(yōu)先級表示該線程被調(diào)度到的難易度,高的更容易被調(diào)度到
  5. 判斷是否為后臺線程。如果是后臺線程,那么該后臺線程不會影響 java 進程的結(jié)束;如果是非后臺線程,JVM 就會等到所有的非后臺線程執(zhí)行完畢,才會結(jié)束運行,因此會影響到總進程的結(jié)束
  6. 是否存活是來判斷線程是否還存在的方法。當創(chuàng)建出 Thread 實例對象時,線程未必就創(chuàng)建了,需要調(diào)用 start 方法,才是真正的創(chuàng)建了線程。當線程中的 run 方法執(zhí)行完畢,線程結(jié)束被銷毀了,創(chuàng)建出的實例對象還沒被銷毀回收。所以說,創(chuàng)建出的實例對象和線程的生命周期是不完全相同的

在線程的狀態(tài)中,除了NEW 和 TERMINATED 以外的狀態(tài)都是活著的

代碼:

public class func8 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            for (int i = 0;i < 5;i ++) {
                System.out.println("新線程~");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"newThread");
        System.out.println("新線程狀態(tài):" +t.getState());
        //創(chuàng)建了對象,沒創(chuàng)建線程
        t.start();
        System.out.println("新線程狀態(tài):" +t.getState());
        //創(chuàng)建了線程
        System.out.println("新線程Id:"+t.getId());
        System.out.println("新線程名稱:"+t.getName());
        System.out.println("新線程是否為后臺線程:" + t.isDaemon());
        System.out.println("新線程是否被中斷:" + t.isInterrupted());
        System.out.println("新線程優(yōu)先級:" + t.getPriority());
        System.out.println("主線程名稱:"+Thread.currentThread().getName());
        while (t.isAlive()) {} //當t線程還存在時,主線程就擱這兒循環(huán)著,直到線程結(jié)束
        System.out.println("新線程狀態(tài):" +t.getState());//線程結(jié)束
    }
}

結(jié)果:

三、創(chuàng)建線程

創(chuàng)建 Thread 類的對象不意味著線程被創(chuàng)建出,start() 方法才是真正的在操作系統(tǒng)內(nèi)部創(chuàng)建一個新的線程,通過重寫 run 方法來描述需要執(zhí)行的任務(wù),從而真正實現(xiàn)了多線程運行。

四、中斷線程

方法一:手動設(shè)置標志位,作為中斷線程的條件

public class func9 {
    private static Boolean flag = false;//手動設(shè)置的標志位 flag
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            while (!flag) {
                //flag 為真時停止循環(huán)
                System.out.println("myThread");
                try {
                    Thread.sleep(1000);//打印一次,阻塞一秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();//創(chuàng)建了線程 t
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag = true;
        //等3秒后,在主線程中將 flag 的值改成 true,從而使線程t循環(huán)條件不成立
    }
}

方法二:使用 Thread 實例中的標志位

public class func10 {
    public static void main(String[] args) {
        Thread t = new Thread() {
            @Override
            public void run() {
                //通過 isInerrupted()判斷標志位是否為true,為true說明線程要退出
                while (!this.isInterrupted()) {
                   System.out.println("my Thread");
                   try {
                       Thread.sleep(1000);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                       //System.out.println("完善工作");
                       //break;
                   }
               }
            }
        };
        t.start();//創(chuàng)建新的線程
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t.interrupt();
        //t線程運行3秒后,通過 interrupt() 方法將標志位設(shè)置為 true
    }
}

結(jié)果:

可以看見當3秒后標志位設(shè)置為 true,希望 t 線程中斷退出時,結(jié)果只是報了個 InterruptedException 異常。

事實上,當調(diào)用 interrupt 方法時,如果線程為就緒狀態(tài),就會直接修改線程中的標志位;如果是阻塞狀態(tài),就會引起 InterruptedException 異常(因為調(diào)用了 sleep 方法,正阻塞著呢,結(jié)果被強行呼醒了)

但收到中斷線程這個信號后,出現(xiàn)了異常,只是單純的打印了一下異常,并沒有對出現(xiàn)的異常進行反應(yīng),于是 t 線程就繼續(xù)循環(huán),就好像中斷線程這個信號只是提醒了一下,線程打個日志就完事,當做沒聽見。

事實上,這樣的機制是有存在的道理的,如果調(diào)用了 interrupt 方法后,線程說中斷就中斷,是非常不符合常理的,此時并不知道線程執(zhí)行到什么地方,收到中斷的信號后,怎么說也要進行收尾工作,由線程自己決定什么時候被銷毀

因此我們要在捕捉到 InterruptedException 異常后,進行工作完善,然后通過 break 跳出循環(huán),結(jié)束線程

方法二和方法一相比更加好。因為方法一中的中斷標志被修改后,即使當時正在 sleep ,也會把當下的 sleep 的時間過完,才會進行下一輪判斷,才知道線程被中斷。方法二即使是在 sleep,收到中斷信號后,就會馬上被喚醒,中斷信息收到的更加的及時。

結(jié)果:

五、線程等待

通過 join() 方法來決定線程執(zhí)行順序(主要控制結(jié)束線程的順序)。

public class func11 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
           for (int i = 0;i < 3;i ++) {
               System.out.println("my Thread~~");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        t1.start();
        //t1.join();
        for (int i = 0;i < 3;i ++) {
            System.out.println("my main!!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

結(jié)果:

在沒有調(diào)用 join 方法時,main 線程和 t1 線程是并發(fā)的,結(jié)果輸出是相間的。調(diào)用 join 方法后,main 線程就會阻塞等待,要等 t1 線程執(zhí)行完畢,才會執(zhí)行 join 方法后的內(nèi)容

不帶參數(shù)的 join 方法,等待結(jié)束的條件就是 t1 線程結(jié)束,沒結(jié)束就會一直死等;該方法也可以帶參數(shù),通過參數(shù)來指定等待時間

六、獲取線程引用

在線程代碼中,需要獲取當前線程對應(yīng)的 Thread 類的實例化對象,才能進行更多的操作

方法一:通過繼承 Thread 類創(chuàng)建的線程,可以在重寫的 run 方法中通過 this 獲取當前線程的實例

在上面的中斷線程中的方法二中就是通過 this.isInterrupted() 來獲取當前實例是否被中斷的信息。

如果將創(chuàng)建線程的方式改成創(chuàng)建 Runnable 實例的方法,當前的run 方法就不是 Thread 類的方法,this 指向的是 Runnable,就沒有辦法獲取 Thread 實例,更沒有辦法使用其中的方法

方法二:通過 Thread 類的 currentThread() 方法,哪個線程調(diào)用了該方法,就返回哪個線程的實例對象

七、線程休眠

該方法在前面經(jīng)常介紹,那就是 sleep 方法

一旦調(diào)用 sleep 方法,線程就會阻塞等待,等待的時間取決于指定的參數(shù)

操作系統(tǒng)是以線程為單位進行調(diào)度的,每個線程都對應(yīng)著一個 PCB,并通過雙向鏈表組織這些 PCB

操作系統(tǒng)調(diào)度 PCB 時,就是從就緒隊列中選出一個 PCB 去 CPU 上執(zhí)行,當執(zhí)行著的線程調(diào)用了 sleep 方法,這個 PCB 就會被移動到阻塞隊列中,等到 sleep 的時間到了,就會回到就緒隊列中,準備好被執(zhí)行

join 方法也會產(chǎn)生阻塞等待,就像線程等待中的例子,main 線程執(zhí)行到 join方法后,就到阻塞隊列中,等待對應(yīng)的 t1 線程執(zhí)行完畢,才會回到就緒隊列中,做好被執(zhí)行的準備

八、線程狀態(tài)

從之前的 Thread 的常見屬性這里的代碼案例可以看出來線程的狀態(tài)不只是就緒和阻塞,即使是阻塞也分成好幾種阻塞類型

//線程的狀態(tài)是一個枚舉類型 Thread.State
//打印 Java 線程中的所有狀態(tài)
public class func13 {
    public static void main(String[] args) {
        for (Thread.State state : Thread.State.values()) {
            System.out.println(state);
        }
    }
}

結(jié)果:

  • NEW:表示 Thread 類的對象創(chuàng)建出,但是線程還沒有被創(chuàng)建,即沒有調(diào)用 start 方法
  • RUNNABLE:就緒狀態(tài)
  • BLOCKED:等待鎖時的狀態(tài)(期待下一篇關(guān)于線程安全的博客)
  • WAITING:通過 wait 方法觸發(fā)(期待之后的博客)
  • TIMED_WAITING:通過 sleep 方法產(chǎn)生
  • TERMINATED:線程已經(jīng)執(zhí)行完畢,但 Thread 類的對象還存在,未被銷毀

總結(jié)

到此這篇關(guān)于Java中Thread類詳解及常用的方法的文章就介紹到這了,更多相關(guān)Java Thread類方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringSecurity報錯authenticationManager must be spec的解決

    SpringSecurity報錯authenticationManager must be 

    這篇文章主要介紹了SpringSecurity報錯authenticationManager must be spec的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 如何通過Java生成一個隨機數(shù)

    如何通過Java生成一個隨機數(shù)

    當我們需要在Java中生成隨機數(shù)時,可以借助JDK中提供的Random類來實現(xiàn),通過使用Random類,我們可以輕松地生成各種類型的隨機數(shù),下面我們就來看看如何利用Random類生成隨機數(shù)吧
    2023-09-09
  • Java中final關(guān)鍵字的深入探究

    Java中final關(guān)鍵字的深入探究

    這篇文章主要給大家介紹了關(guān)于Java中final關(guān)鍵字的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Java可變參數(shù)的應(yīng)用小結(jié)

    Java可變參數(shù)的應(yīng)用小結(jié)

    這篇文章主要介紹了Java可變參數(shù)的應(yīng)用小結(jié),實現(xiàn)同一個函數(shù)名,不同參數(shù)個數(shù),實現(xiàn)的方法相同,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-10-10
  • Java?使用geotools讀取tiff數(shù)據(jù)的示例代碼

    Java?使用geotools讀取tiff數(shù)據(jù)的示例代碼

    這篇文章主要介紹了Java?通過geotools讀取tiff,一般對于tiff數(shù)據(jù)的讀取,都會借助于gdal,本文結(jié)合示例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-04-04
  • RestTemplat中關(guān)于getForobject方法的使用

    RestTemplat中關(guān)于getForobject方法的使用

    這篇文章主要介紹了RestTemplat中關(guān)于getForobject方法的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • JAVA面試題之緩存擊穿、緩存穿透、緩存雪崩的三者區(qū)別

    JAVA面試題之緩存擊穿、緩存穿透、緩存雪崩的三者區(qū)別

    當服務(wù)器QPS比較高,并且對數(shù)據(jù)的實時性要求不高時,往往會接入緩存以達到快速Response、降低數(shù)據(jù)庫壓力的作用,常用來做緩存的中間件如Redis等。本文主要介紹了JAVA面試時??嫉木彺鎿舸?、穿透、雪崩場景三者區(qū)別,有興趣的小伙伴可以看一下
    2021-11-11
  • Spring Boot 排除某個類加載注入IOC的操作

    Spring Boot 排除某個類加載注入IOC的操作

    這篇文章主要介紹了Spring Boot 排除某個類加載注入IOC的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java通過itext生成pdf的干貨教程

    java通過itext生成pdf的干貨教程

    這篇文章主要介紹了java通過itext生成pdf的相關(guān)資料,文中的示例代碼講解詳細,對我們學(xué)習(xí)Java有一定幫助,需要的可以參考一下
    2022-06-06
  • Spring Initializr中生成的mvnw有什么用

    Spring Initializr中生成的mvnw有什么用

    這篇文章主要介紹了Spring Initializr中生成的mvnw有什么用,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01

最新評論

梓潼县| 胶南市| 桐庐县| 错那县| 汶上县| 平凉市| 五指山市| 板桥市| 稻城县| 通州市| 祁东县| 邳州市| 鹤山市| 淳化县| 岳池县| 临泉县| 伊宁县| 河北省| 张家港市| 五指山市| 承德县| 启东市| 根河市| 石狮市| 阳新县| 娄底市| 南平市| 井陉县| 田阳县| 浦城县| 鸡西市| 岢岚县| 左云县| 巍山| 屏东县| 北辰区| 尼勒克县| 辽宁省| 和硕县| 南华县| 永川市|