java-多線程篇<上>

來源:互聯網
上載者:User

標籤:

1.線程和進程的概念 

   1.1.進程(Process):擁有獨立的記憶體空間,每個獨立執行的程式稱為進程
   1.2.線程(Thread):線程是一個程式內部的一條執行路徑,Java虛擬機器允許應用程式並發地運行多個執行線程
   1.3.線程和進程的區別
           每個進程都有獨立的代碼和資料空間(進程上下文),進程間的切換開銷大
           線程: 同一進程內的線程共用代碼和資料空間,線程切換的開銷小
           多進程: 在作業系統中能同時運行多個任務(程式)
           多線程: 在同一應用程式中多條執行路徑同時執行

2.線程的建立與啟動   

   第一種:繼承Thread類,重寫run方法

   第二種:實現Runnable介面,重寫run方法

3.兩種建立方式的比較   
   3.1使用Runnable介面
             還可以從其他類繼承;
             保持程式風格的一致性。
   3.2直接繼承Thread類
             不能再從其他類繼承;
             編寫簡單,可以直接操縱線程
   使用實現Runnable介面的方式建立線程時可以為相同程式碼的多個線程提供共用的資料。

4.線程小結 
   4.1.Java的線程是通過java.lang.Thread類來實現的。
   4.2.當程式啟動運行時,JVM會產生一個線程(主線程),主方法(main方法)就是在這個線程上啟動並執行。
   4.3.可以通過建立Thread的執行個體來建立新的線程。
         a.每個線程都是通過某個特定Thread對象所對應的方法run()來完成其操作的,方法run()稱為線程體。
         b.通過調用Thread類的start()方法來啟動一個線程。線程進入Runnable(可運行)狀態,它將向線程

            調度器註冊這個線程。
         c.調用start()方法並不一定馬上會執行這個線程,正如上面所說,它只是進入Runnable 而不是 

           Running。

   4.4.每個線程都有一個優先順序,一個標識名,多個線程可以同步。沒有指定標識名時,會自動為其產生一個

         高優先順序線程的執行優先於低優先順序線程。每個線程都可以或不可以標記為一個精靈。當某個線程 

         中啟動並執行代碼建立一個新 Thread 對象時,該新線程的初始優先順序被設定為建立線程的優先順序,並且

         若且唯若建立線程是守護線程時,新線程才是精靈。

  4.5.Java虛擬機器退出的情況

  • 調用了 Runtime 類的 exit 方法,並且安全管理器允許退出操作發生。
  • 非守護線程的所有線程都已停止運行,無論是通過從對 run 方法的調用中返回,還是通過拋出一個傳播到

     run 方法之外的異常

  注意,不要直接在程式中調用線程的run()方法。

5.線程的基本使用方法 

  •    static Thread currentThread ();//返回當前正在執行的線程對象的引用
  •    static void yield ();//暫停當前線程一下下。
  •    static void sleep (long millis);//線程睡眠(暫停執行)
  •    上面三個都是靜態方法,其他的一般不是
  •    void start();//使線程啟動,進入runnable狀態。
  •    boolean isAlive();//判斷該線程是否處於活動狀態
  •    boolean isDaemon();//判斷是否是守護線程
  •    Thread.State getState();//返回該線程的狀態
  •    void setName(String name);//改變線程名稱
  •    void setDaemon(boolean on);//true則為守護進程,false為使用者進程。

 6.線程的調度   

  1. 線程睡眠: Thread.sleep(long miao);//使線程進入阻塞狀態,睡眠結束後進入就緒(Runnable)狀態
  2. 線程讓步: Thread.yield();//暫停當前執行線程,將執行機會讓給同等或更高優先順序的線程執行,但是這個時間不能控制.是不確定的.只是讓當前線程暫停一下下.
     
  3. 線程加入: join();//throws InterruptedException 。當前線程調用另一個線程的join方法,則當前線程

                         轉入waiting狀態,直到調用join()方法的線程執行完畢,當前線程再由阻塞轉為就緒狀態。

      4.線程等待:Object類中的wait()方法,導致當前線程等待,直到其他線程調用此對象的notify()方法或notifyAll

                      ()方法喚醒該線程。

    5.線程喚醒:Object類的notify()方法,喚醒在。此對象監視器上等待的某個單個線程。選擇是隨意的。、

                      Object類的notifyAll()方法,喚醒在此對象監視器上等待的所有線程。

     注意:這三個方法(wait,notify,notifyAll)只能在被同步化(synchronized)的方法或代碼塊中使用。

7.線程停止     

  • 如果run方法中執行的是一個重複執行的迴圈,可以提供一個標誌來控制迴圈是否執行。
  • 如果線程是因為執行了sleep()方法或wait()方法而進入了阻塞狀態,此時想停止它的話可以使用interrupt()方法

        程式會拋出InterruptException異常。

  • 如果程式因為輸入/輸出的等待而阻塞,基本上是必須等待輸入/輸出的動作完成才能離開阻塞狀態。無法通過interrupt

        方法使得線程離開run方法,要想離開只能引發一個異常。

7.1 線程的終止

  • 因為run方法的正常退出而自然死亡
  • 因為一個沒有捕獲的異常終止了run方法而意外死亡

8.線程狀態的轉換  

    建立(new)---->[阻塞解除]----->就緒(runnable)---->運行(running)--->[阻塞]---->死亡(dead)

    建立狀態(new):新建立一個線程對象。

    就緒狀態(runnable):其他線程調用了該線程的start方法後,該狀態的線程位於可運行線程池中,變得可運行,等待

                                     擷取cpu使用權。擷取了cpu,執行程式代碼時也屬於就緒狀態。

    運行狀態(running):執行run方法。

    阻塞狀態(blocked):阻塞狀態是因為線程由於某個原因而放棄cpu的使用權,而暫時停止運行,直到線程進入就緒狀態

                                   才有機會進入運行狀態。阻塞情況有三種:

                                 1.同步阻塞:啟動並執行線程在擷取對象的同步鎖時,如果該同步鎖被其他線程佔用,則jvm將它放入鎖池中

                                 2.等待阻塞:啟動並執行線程執行wait的方法時,jvm會把該線程放入等待池中。

                                 3.其他阻塞:啟動並執行線程執行sleep()方法或join()方法,或發出I/O請求時,將進入阻塞狀態

    死亡狀態(dead):線程執行完或因異常退出run方法,線程結束生命週期。

    注意:調用yield()方法並沒有進入阻塞(blocked)狀態

 

9.調整線程的優先順序      

    Java提供了一個線程調度器來監控程式中啟動後進入就緒狀態的所有線程。優先順序高的線程會獲得較多的運行機會

    Java線程的優先順序用int表示,取值1~10,Thread類的三個靜態常量:MAX_PRIORITY=10,MIN_PRIORITY=1

    NORM_PRIORITY=5(預設優先順序取值為5).

    Thread類的setPriority(),getPriority()方法可以設定和擷取線程的優先順序

    注意:優先順序高的只是得到cpu的機會機率多一些

10.線程同步(同步鎖)  

      在Java語言中,引入了對象互斥鎖的概念,保證共用資料操作的完整性,每個對象都對應於一個可稱為"互斥鎖"

      的標記,這個標記保證在任何時刻,只能有一個線程訪問對象。

      關鍵字synchronized用來與對象互斥鎖聯絡,當某個對象用synchronized修飾時,表明該對象在任何時刻

      只能由一個線程訪問。

      注意:同步鎖即synchronized(參數)裡的參數必須是參考型別,如成員變數(必須是引用類類型:String)

               成員方法(方法的傳回值必須是參考型別,不能是int,char),this(即本身對象),this.getClass()//類

11.Synchronized關鍵字

     同步代碼塊: synchronized(this){需要同步的代碼;}

     同步方法:public  synchronized void method(){...}

12.死結問題

    有兩個線程,x和y,x線程拿到了A對象鎖後執行代碼,y線程拿到了B對象鎖後執行代碼,如果這時x線程還要取

    B對象鎖,而y線程也要取A對象鎖,則大家拿著各自的鎖不放,就會導致死結的問題。

    解決死結的辦法之一就是:加大鎖的粒度。

13.多安全執行緒問題

      當run()方法中的代碼操作到了成員變數(共用資料)時,就會出現多安全執行緒問題(線程不同步問題)

      編程技巧:在方法中盡量少操作成員變數,多使用局部變數。

14.容器類的安全執行緒

     大多數的容器類預設都沒有考慮安全執行緒問題,程式必須自行實現同步:

     a.用synchronized來鎖住這個對象

         synchronized (list){  list.add(...) ;}

     b.用Collections類的synchronizedXXX()方法返回一個同步化的容器物件

        List list=Collections.synchronizedList(new ArrayList());

        這種方式在迭代時仍要用synchronized修飾。

List list = Collections.synchronizedList(new ArrayList());
...
synchronized(list) {
Iterator i = list.iterator(); while (i.hasNext()) {foo(i.next());}}

    JDK 5.0之後,新增了java.util.concurrent這個包,其中包括了一些確保安全執行緒的容器類,

    如ConcurrentHashMap,CopyOnWriteArrayList,CopyOnWriteArraySet,它們在效率

    與安全性上取得了較好的平衡。

總結:

      wait():釋放cpu執行權,釋放鎖。

      sleep():釋放cpu執行權,不釋放鎖。

JDK1.5版本提供了一些新的對象,最佳化了等待喚醒機制。

   1,將synchronized 替換成了Lock介面。
       將隱式鎖,升級成了顯示鎖。
       Lock 
       擷取鎖:lock();
       釋放鎖:unlock();注意:釋放的動作一定要執行,所以通常定義在finally中。
       擷取Condition對象:newCondition();
   2,將Object中的wait,notify,notifyAll方法都替換成了Condition的await,signal,signalAll。
       和以前不同是:一個同步代碼塊具備一個鎖,該所以具備自己的獨立wait和notify方法。
       現在是將wait,notify等方法,封裝進一個特有的對象Condition,而一個Lock鎖上可以有多個Condition對象。

    線程中一些常見方法:
     setDaemon(boolean):將線程標記為後台線程,後台線程和前台線程一樣,開啟,一樣搶執行權運行,
       只有在結束時,有區別,當前台線程都運行結束後,後台線程會自動結束。

     join():什麼意思?等待該線程結束。當A線程執行到了B的.join方法時,A就會處於凍結狀態。
     A什麼時候運行呢?當B運行結束後,A就會具備運行資格,繼續運行。

     加入線程,可以完成對某個線程的臨時加入執行。

     注意:啟動一個jvm時,會有一個前台線程:主線程(執行main方法),還有一個後台線程:記憶體回收機制線程。

   

 

 

java-多線程篇<上>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.