<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      JAVA多線程(三)--線程生命周期

      一、線程的狀態

      在Java中,線程在創建并啟動后,不是一開始就進入執行狀態,也不是一直處于執行狀態。在線程的生命周期中,它要經過新建(NEW)、就緒(RUNNABLE)、阻塞(BLOCKED)、等待(WAITING)、超時等待(TIME_WAITING)、終止(TERMINATED)六種狀態。線程運行后,CPU會在多條線程間切換,于是線程狀態也會多次在運行和阻塞間切換。
      image

      線程狀態枚舉源碼(點擊查看代碼)
          public enum State {
              /**
               * Thread state for a thread which has not yet started.
               */
              NEW,
      
              /**
               * Thread state for a runnable thread.  A thread in the runnable
               * state is executing in the Java virtual machine but it may
               * be waiting for other resources from the operating system
               * such as processor.
               */
              RUNNABLE,
      
              /**
               * Thread state for a thread blocked waiting for a monitor lock.
               * A thread in the blocked state is waiting for a monitor lock
               * to enter a synchronized block/method or
               * reenter a synchronized block/method after calling
               * {@link Object#wait() Object.wait}.
               */
              BLOCKED,
      
              /**
               * Thread state for a waiting thread.
               * A thread is in the waiting state due to calling one of the
               * following methods:
               * <ul>
               *   <li>{@link Object#wait() Object.wait} with no timeout</li>
               *   <li>{@link #join() Thread.join} with no timeout</li>
               *   <li>{@link LockSupport#park() LockSupport.park}</li>
               * </ul>
               *
               * <p>A thread in the waiting state is waiting for another thread to
               * perform a particular action.
               *
               * For example, a thread that has called <tt>Object.wait()</tt>
               * on an object is waiting for another thread to call
               * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
               * that object. A thread that has called <tt>Thread.join()</tt>
               * is waiting for a specified thread to terminate.
               */
              WAITING,
      
              /**
               * Thread state for a waiting thread with a specified waiting time.
               * A thread is in the timed waiting state due to calling one of
               * the following methods with a specified positive waiting time:
               * <ul>
               *   <li>{@link #sleep Thread.sleep}</li>
               *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
               *   <li>{@link #join(long) Thread.join} with timeout</li>
               *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
               *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
               * </ul>
               */
              TIMED_WAITING,
      
              /**
               * Thread state for a terminated thread.
               * The thread has completed execution.
               */
              TERMINATED;
          }
      

      1、新建狀態(NEW)

      當使用new關鍵字創建一個新的線程時,線程就處于新建狀態(NEW)了。此時JVM為其分配內存,并初始化成員變量的值。

      2、就緒狀態(RUNNABLE)

      當線程對象調用start()方法時,該線程就處于就緒狀態(RUNNABLE)。JVM會為其創建方法調用棧和程序計數器,等待調用運行。

      運行狀態(RUNNING) 如果就緒線程獲得了CPU執行,開始執行run()方法的線程執行體,則該線程處于運行狀態(RUNNING),實際在Java源碼中并沒有維護該狀態,它被包含在就緒狀態中。

      3、阻塞狀態(BLOCKED)

      阻塞狀態(BLOCKED)是指線程由于某種原因放棄了CPU使用權,暫時停止運行。知道線程進入就緒狀態(RUNNABLE),才有機會再次獲得CPU使用權轉到運行狀態(RUNNING)。
      阻塞狀態分三種:

      • 等待阻塞(o.wait()->等待隊列)
        運行狀態的線程執行o.wait()方法,JVM會把該線程放入等待隊列中。
      • 同步阻塞(lock->鎖池)
        運行狀態的線程在獲取對象的同步鎖時,若該同步鎖在被別的線程使用,那么JVM會把該線程放入鎖池中(lock pool)。
      • 其他阻塞(sleep/join)
        運行狀態的線程執行Thread.sleep(long ms)t.join()方法,或發出了I/O請求時,JVM會把該線程置為阻塞狀態。當sleep()超時、join()等待線程終止或超時、I/O請求處理完畢時,線程重新轉入就緒狀態(RUNNABLE)

      4、等待(WAITING)

      等待狀態,沒有超時時間(無限等待),需要被其他線程或者其他的中斷操作。
      執行o.wait()t.join()LockSupport.park()

      5、超時等待(TIME_WAITING)

      與等待不同的是,不是無限等待,超時后自動返回
      執行t.sleep(),帶參數的o.wait(long)等可以實現

      6、終止狀態(TERMINATED)

      線程會已以下三種方式結束,結束后就是終止狀態。

      • 正常結束:
        run()call()方法執行完成,線程正常結束。

      • 異常結束:
        線程拋出一個未捕獲的ExceptionError.

      • 調用stop()方法:
        直接調用線程的stop()方法結束線程。該方法通常容易導致死鎖,不推薦使用。

      二、線程基本方法

      1、start()

      Thread通過start()方法來啟動一個線程,這時此線程處于就緒狀態,并沒有馬上運行

      2、run()

      run()方法為線程體,它包含了該線程要執行的內容。當線程進入運行狀態時,開始執行run()方法中的代碼。run()方法代碼執行結束,此線程終止。

      3、wait()

      wait()方法是Object類中的方法。調用該方法的線程進入WAITING狀態,只有等待其他線程通知或被中斷才會返回。

      調用wait()方法后,會釋放對象鎖,進入等待鎖定池,只有針對該對象調用notify()方法后本線程才進入對象鎖定池準備獲取對象鎖進入運行狀態。因此,wait()方法一般被用在同步方法或同步代碼塊中。

      4、sleep(long)

      sleep(long)方法是Thread類中的方法sleep(long)方法導致線程進入休眠,進入TIME_WAITING狀態,與wait()方法不同的是,sleep(long)不會釋放對象鎖
      sleep(long)方法會讓線程暫停執行指定的時間,讓出CPU資源,但是它的監控狀態會一直保持,當指定的時間到了會自動恢復就緒狀態。

      5、yield()

      線程讓步。 yield()方法會使當前線程讓出CPU使用權,讓其他線程重新競爭CPU使用權。一般情況下,優先級高的線程有更高的概率成功競爭到CPU使用權,但這不是絕對的,有的操作系統對線程優先級并不敏感

      6、interrupt()

      線程中斷。 中斷一個線程,其本意是給這個線程一個通知信號,會影響這個線程內部的一個中斷標識位。這個線程本身并不會因此而改變狀態(如阻塞、終止等)。

      • 調用interrupt()方法并不會中斷一個線程。運行中的線程并不會因此而終止,只是改變了線程內部維護的中斷標識位而已。
      • 若調用sleep(long)使線程進入TIMED_WAITING狀態,此時調用interrupt()方法,會拋出InterruptedException異常,使線程提前結束TIMED_WAITING狀態。
      • 許多申明拋出InterruptedException異常的方法,拋出異常前,都會清楚中斷標識位,所以拋出異常后,調用isInterrupted()方法將會返回false.
      • 中斷狀態是線程固有的一個標識位,可以通過此標識位安全的終止線程。通過調用interrupt()方法,在run()方法內可以判斷t.isInterrupted()的值來優雅的終止線程。

      7、join()

      等待其他線程終止。 在當前線程中調用一個線程的join()方法,則當前線程轉為阻塞狀態,等到調用join()方法的線程終止,當前線程再由阻塞狀態轉為就緒狀態。

      很多情況下,主線程創建了子線程,需要用到子線程的返回結果,也就是主線程需要在子線程結束之后再結束,這時就需要用到join()方法。

      System.out.println("主線程執行開始");
      MyThread myThread = new MyThread();
      myThread.start();
      myThread.join();
      System.out.println("主線程執行結束");
      
      結果必然為:
      主線程執行開始
      MyThread running
      主線程執行結束
      

      8、notify()

      線程喚醒。 notify()Object類中的方法,喚醒在此對象監視器上等待的單個線程,如果有多個線程都在該對象上等待,則會選擇喚醒其中一個線程,選擇是任意的,并在對實現做出決定時發生。類似的方法還有notifyAll(),喚醒在此監視器上的所有線程。

      三、終止線程的方式

      1、正常運行結束

      程序運行結束,線程自動終止。

      2、使用退出標志終止線程

      某些線程需要長時間運行,只有滿足某些條件的情況下,才能終止這些線程。可以使用一個變量來控制循環。

      // 使用 volatile 關鍵字,保障同一時刻只能有一個線程來修改它的值
      public class MyThread extends Thread{
          public volatile boolean exit = false;
          @Override
          public void run(){
              while(!exit){
                  System.out.println("do something");
              }
          }
      }
      

      3、Interrupt方法終止線程

      使用interrupt()方法來終止線程,有兩種情況:

      • 1、線程處于阻塞狀態。 如使用了sleep、同步鎖的wait,socket中的receiver、accept等方法時會使線程處于阻塞狀態。當調用線程的interrupt()方法時,會拋出InterruptedException異常。通過代碼捕獲該異常然后break跳出循環狀態,從而結束這個線程的運行。一定要先捕獲異常之后通過break來跳出循環,才能正常結束run方法。

      • 2、線程未處于阻塞狀態。 使用 isInterrupted() 判斷線程的中斷標志來退出循環。當使用interrupt()方法時,中斷標志就會置 true,和使用自定義的標志來控制循環是一樣的道理。

      public class MyThread extends Thread{
          @Override
          public void run(){
              // 非阻塞過程中通過判斷中斷標志來退出
              while(!isInterrupted()){
                  System.out.println("do something");
                  try {
                      // 阻塞過程中通過捕獲異常來退出
                      Thread.sleep(500);
                  }catch (InterruptedException e){
                      e.printStackTrace();
                      break;
                  }
              }
          }
      }
      

      4、stop方法終止線程(線程不安全)

      線程中可以直接使用t.stop()方法來強行終止線程。
      不安全原因:當調用stop()方法后,創建子線程的線程就會拋出ThreadDeath的Error錯誤,并且會釋放子線程所持有的所以鎖。一般加鎖的模塊都是為了保護數據的一致性,調用stop()方法后,該線程持有的鎖突然被釋放,那么被保護的數據就有可能出現數據不一致的情況,其他線程再使用這些被破壞的數據時就會出現問題。因此,不推薦使用stop()

      四、守護線程

      1、定義: 守護線程是指在程序運行的時候在后臺提供一種通用服務的線程,比如垃圾回收線程就是一個很稱職的守護者,并且這種線程并不屬于程序中不可或缺的部分。因此,當所有的非守護線程結束時,程序也就終止了,同時會殺死進程中的所有守護線程。反過來說,只要任何非守護線程還在運行,程序就不會終止。

      2、設置: 可以通過setDaemon(true)來設置線程為守護線程。

      • setDaemon(true)方法必須要在start()方法之前調用,否則會拋出IllegalThreadStateException異常。不能把正常運行的用戶線程設置為守護線程。
      • 在守護線程中產生的新線程也是守護線程。
      • 守護線程應該永遠不去訪問固有資源,如文件、數據庫,因為它會在任何時候甚至在一個操作的中間發生中斷。

      3、生命周期: 守護進程(Daemon)是運行在后臺的一種特殊進程。它獨立于控制終端并且周期性地執行某種任務或等待處理某些發生的事件。也就是說守護線程不依賴于終端,但是依賴于系統,與系統“同生共死”。當 JVM 中所有的線程都是守護線程的時候,JVM 就可以退出了;如果還有一個或以上的非守護線程則 JVM 不會退出。

      posted @ 2023-02-26 14:33  殘忍的幻象飯團  閱讀(65)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 精品无码一区二区三区水蜜桃| 国产福利酱国产一区二区| 孕妇特级毛片ww无码内射| 国产v亚洲v天堂a无码99 | 亚洲sm另类一区二区三区| 一级片一区二区中文字幕| 国产欧美精品一区二区三区| 内射无套内射国产精品视频| 国产精品久久中文字幕| 欧美三级在线播放| 一区二区三区激情免费视频 | 无码福利一区二区三区| 国产特级毛片AAAAAA视频| 班戈县| 国产亚洲一在无在线观看| 国产AV影片麻豆精品传媒| 昌图县| 污网站在线观看视频| 亚洲国产高清第一第二区| 国产精品永久免费无遮挡| 亚洲国产成人精品av区按摩| 精品亚洲欧美高清不卡高清| 在线涩涩免费观看国产精品| 少妇被爽到高潮喷水久久欧美精品| 久久96热人妻偷产精品| 国产精品天干天干综合网| 弋阳县| 色偷偷女人的天堂亚洲网| 日本中文一二区有码在线| 无码专区 人妻系列 在线| 成人精品网一区二区三区| 亚洲国产大胸一区二区三区| 精品一区二区不卡免费| 日韩一区二区三区理伦片 | 双乳奶水饱满少妇呻吟免费看| 亚洲精品一区| 日韩一区二区黄色一级片| 狠狠噜天天噜日日噜| 亚洲V天堂V手机在线| 亚洲美免无码中文字幕在线 | 亚洲国产精品日韩专区av|