1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
      java中ThreadAPI的調(diào)用規(guī)則是什么

      這篇文章將為大家詳細(xì)講解有關(guān)java中Thread API的調(diào)用規(guī)則是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

      師宗網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)建站!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)建站成立于2013年到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)建站

      start一個(gè)Thread

      Thread中有兩個(gè)方法,一個(gè)是start方法,一個(gè)是run方法,兩個(gè)都可以調(diào)用,那么兩個(gè)有什么區(qū)別呢?

      先看一下start方法:

      public synchronized void start() {
      
              if (threadStatus != 0)
                  throw new IllegalThreadStateException();
              group.add(this);
              boolean started = false;
              try {
                  start0();
                  started = true;
              } finally {
                  try {
                      if (!started) {
                          group.threadStartFailed(this);
                      }
                  } catch (Throwable ignore) {
                  }
              }
          }
      
          private native void start0();

      start()是一個(gè)synchronized的方法,通過它會(huì)去調(diào)用native的start0方法,而最終將會(huì)調(diào)用Thread的run()方法。

      我們知道,創(chuàng)建一個(gè)Thread有兩種方式,一種是傳入一個(gè)Runnable,一個(gè)是繼承Thread,并重寫run()方法。

      如果我們直接調(diào)用Thread的run()方法會(huì)發(fā)生什么事情呢?

      先看一下run方法的定義:

          public void run() {
              if (target != null) {
                  target.run();
              }
          }

      默認(rèn)情況下, 這個(gè)target就是一個(gè)Runnable對(duì)象,如果Thread是通過Runnable來構(gòu)建的話,調(diào)用Thread.run()會(huì)在當(dāng)前線程中運(yùn)行run方法中的內(nèi)容。

      如果Thread是以其形式構(gòu)建,并且沒有重新run()方法,那么直接調(diào)用Thread.run()將什么都不會(huì)做。

          public void wrongStart(){
              Runnable runnable= ()-> System.out.println("in thread running!");
              Thread thread= new Thread(runnable);
              thread.run();
          }
      
          public void correctStart(){
              Runnable runnable= ()-> System.out.println("in thread running!");
              Thread thread= new Thread(runnable);
              thread.start();
          }

      所以,上面兩種調(diào)用方式,只有第二種是正確的。

      不要使用ThreadGroup

      Thread中有個(gè)字段類型是java.lang.ThreadGroup,這個(gè)主要是用來給Thread進(jìn)行分組,我們看下Thread的這個(gè)構(gòu)造函數(shù):

       public Thread(ThreadGroup group, Runnable target) {
              this(group, target, "Thread-" + nextThreadNum(), 0);
          }

      上面的構(gòu)造函數(shù)可以在傳入runnable的同時(shí)傳遞一個(gè)ThreadGroup對(duì)Thread進(jìn)行分組。

      如果沒有指定ThreadGroup,那么將會(huì)為其分配一個(gè)默認(rèn)的default group。

      ThreadGroup是做什么的呢?ThreadGroup是java 1.0引入的方法,主要是一次性的對(duì)一組thread進(jìn)行操作。我們可以調(diào)用ThreadGroup.interrupt()來一次性的對(duì)整個(gè)Group的Thread進(jìn)行interrupts操作。

      雖然ThreadGroup提供了很多有用的方法,但是其中很多方法都被廢棄了,比如:allowThreadSuspension(), resume(), stop(), 和 suspend(),并且ThreadGroup中還有很多方法是非線程安全的:

      • ThreadGroup.activeCount()

      這個(gè)方法主要是用來統(tǒng)計(jì)一個(gè)ThreadGroup中活動(dòng)的線程個(gè)數(shù),這個(gè)方法會(huì)統(tǒng)計(jì)還未啟動(dòng)的線程,同時(shí)也會(huì)受系統(tǒng)線程的影響,所以是不準(zhǔn)確的。

      • ThreadGroup.enumerate()

      這個(gè)方法是將ThreadGroup和子group的線程拷貝到一個(gè)數(shù)組中,但是如果數(shù)組太小了,多余的線程是會(huì)被自動(dòng)忽略的。

      ThreadGroup本身有一個(gè) stop() 方法用來停止所有的線程,但是stop是不安全的,已經(jīng)被廢棄了。

      那么我們?cè)撛趺慈グ踩耐V购芏鄠€(gè)線程呢?

      使用executor.shutdown()就可以了。

      不要使用stop()方法

      剛剛講了ThreadGroup中不要調(diào)用stop()方法,因?yàn)閟top是不安全的。

      調(diào)用stop方法會(huì)立馬釋放線程持有的所有的鎖,并且會(huì)拋出ThreadDeath異常。

      因?yàn)闀?huì)釋放所有的鎖,所以可能會(huì)造成受這些鎖保護(hù)的對(duì)象的狀態(tài)發(fā)生不一致的情況。

      替代的方法有兩種,一種是使用volatile flag變量,來控制線程的循環(huán)執(zhí)行:

          private volatile boolean done = false;
      
          public void shutDown(){
              this.done= true;
          }
      
          public void stopWithFlag(){
      
              Runnable runnable= ()->{
                  while(!done){
                      System.out.println("in Runnable");
                  }
              };
      
              Thread thread= new Thread(runnable);
              thread.start();
              shutDown();
          }

      另外一種方法就是調(diào)用interrupt(), 這里我們要注意interrupt()的使用要點(diǎn):

      1. 如果當(dāng)前線程實(shí)例在調(diào)用Object類的wait(),wait(long)或wait(long,int)方法或join(),join(long),join(long,int)方法,或者在該實(shí)例中調(diào)用了Thread.sleep(long)或Thread.sleep(long,int)方法,并且正在阻塞狀態(tài)中時(shí),則其中斷狀態(tài)將被清除,并將收到InterruptedException。

      2. 如果此線程在InterruptibleChannel上的I/O操作中處于被阻塞狀態(tài),則該channel將被關(guān)閉,該線程的中斷狀態(tài)將被設(shè)置為true,并且該線程將收到j(luò)ava.nio.channels.ClosedByInterruptException異常。

      3. 如果此線程在java.nio.channels.Selector中處于被被阻塞狀態(tài),則將設(shè)置該線程的中斷狀態(tài)為true,并且它將立即從select操作中返回。

      4. 如果上面的情況都不成立,則設(shè)置中斷狀態(tài)為true。

      先看下面的例子:

          public static void main(String[] args)  {
              Runnable runnable= ()->{
                  while (!Thread.interrupted()) {
                   System.out.println("in thread");
                  }
              };
              Thread thread= new Thread(runnable);
              thread.start();
              Thread.sleep(5000);
              thread.interrupt();
          }

      我們?cè)趙hile循環(huán)中調(diào)用了Thread.interrupted()方法用來判斷線程是否被設(shè)置了中斷位,然后在main方法中調(diào)用了thread.interrupt()來設(shè)置中斷,最終可以正確的停止Thread。

      注意,這里運(yùn)行的Thread并沒有被阻塞,所以并不滿足我們上面提到的第一個(gè)條件。

      下面我們?cè)倏匆粋€(gè)例子:

          public static void main(String[] args)  {
              Runnable runnable= ()->{
                  while (!Thread.interrupted()) {
                   System.out.println("in thread");
                      try {
                          Thread.sleep(5000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
              };
      
              Thread thread= new Thread(runnable);
              thread.start();
              thread.interrupt();
          }

      這個(gè)例子和上面的例子不同之處就是在于,Thread中調(diào)用了sleep方法,導(dǎo)致Thread被阻塞了,最終滿足了第一個(gè)條件,從而不會(huì)設(shè)置終端位,只會(huì)拋出InterruptedException,所以這個(gè)例子中線程是不會(huì)被停止的,大家一定要注意。

      wait 和 await 需要放在循環(huán)中調(diào)用

      為什么要放在循環(huán)中呢?因?yàn)槲覀兿M鹷ait不是被錯(cuò)誤的被喚醒,所以我們需要在wait被喚醒之后,重新檢測(cè)一遍條件。

      錯(cuò)誤的調(diào)用是放在if語句中:

      synchronized (object) {
        if () {
          object.wait();
        }
        // Proceed when condition holds
      }

      正確的方法是放在while循環(huán)中:

      synchronized (object) {
        while () {
          object.wait();
        }
        // Proceed when condition holds
      }

      關(guān)于java中Thread API的調(diào)用規(guī)則是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。


      網(wǎng)站標(biāo)題:java中ThreadAPI的調(diào)用規(guī)則是什么
      文章源于:http://ef60e0e.cn/article/geceeo.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        锡林浩特市| 郎溪县| 泌阳县| 军事| 新干县| 马鞍山市| 晋中市| 江川县| 东明县| 九江县| 蒲城县| 瑞昌市| 荆门市| 甘南县| 德兴市| 炉霍县| 留坝县| 遂宁市| 香格里拉县| 龙泉市| 合肥市| 曲阳县| 台东市| 格尔木市| 枣阳市| 札达县| 布拖县| 和硕县| 芒康县| 玉林市| 秦安县| 二连浩特市| 南宁市| 海南省| 岳阳市| 和林格尔县| 厦门市| 扎囊县| 五台县| 宁陵县| 徐汇区|