1. 程式人生 > >Java 執行緒(Thread)技術與深入理解

Java 執行緒(Thread)技術與深入理解

Thread基礎部分

在各種程式語言中都有thread(執行緒)技術,執行緒保證在一個main中(主執行緒)可以同時進行兩個或多個不同的事件,通俗點說就是你在上廁所的同時還可以玩手機,是吧!美滋滋。而Thread就相當於提供了同時做兩件事的條件和環境。接下來在深入一點理解計算機中的Thread技術,Thread技術本質上並不是使事情同時來進行,而是使事件看起來是同時進行的。舉個例子吧:

     先在有個Buddhist(和尚)和一個Confucian(秀才),他們分別要這樣兩件事,Buddhist每天念100遍經文“ma mi ma mi hong 。。。”,Confucian每天要念200遍三字經“人之初,性本善。。。”,他們兩個每天是在各自做各自的事情,相當於兩個Threads。從計算機的角度講,相當於計算機先讓Buddhist念幾遍經文,在讓Confucian念幾遍三字經,不過計算機讓每個人唸的時間很短,而兩個人又唸的很快(計算機處理速度快),人肉眼看來就相當於兩個人在同時進行各自的事情。

專業一點講:在計算機系統中有個緩衝區,在緩衝區中多個執行緒排著隊(允許有優先順序)等待系統調取執行,執行的時候每個執行緒只分配很端的時間(微秒),就這樣這些執行緒執行完後可以設定一個睡眠時間(sleep)使本執行緒先休息一下給其他執行緒騰點cpu,等sleep結束之後本執行緒會進入緩衝區中排隊等待下次被執行(注:並不是一sleep結束就立刻被執行)。

//Create Thread

(1)extands Thread實現

        public class Buddhist extends Thread   //繼承Thread

        {

               public void run( )   //重寫run method

              {

                 Thread.sleep(100);  //sleep 100ms

                  執行體       //Buddhist唸經

              }

      }

  Buddhist bhst=new Buddhist( );

  bhst.start( );    //Thread的入後(啟動)

 

(2)Runable interface實現

        public class Buddhist implements   Runnable   //繼承Thread的指定interface

        {

               public void run( )   //重寫run method

              {

                 Thread.sleep(100);  //sleep 100ms

                  執行體       //Buddhist唸經

              }

       }

  Thread t=new Thread(new Buddhist( ) );

t.start( ) ;

 

(3)匿名類

  Thread t=new Thread()

    {

        public void run( )

        {  執行體 }

    }

    t.start( );


Thread高階部分(同步機制與通知機制)

(1)同步機制:

      當兩個或多個執行緒同時訪問一個數據的時候就容易出現問題。比如一個執行緒從byte[ ] data中寫資料,另一個執行緒從data中讀資料,由於兩個執行緒分別工作一會讓另一個工作一會,這就容易導致一個執行緒還沒寫好而另一個執行緒就要讀資料,最終會導致資料出現偏差而影響程式正常的進行,而程式設計師還不容易查到原因(並不是語法錯誤)。此時就映入了同步(synchornized)機制,其實就是C++中的互斥鎖機制,都伴隨著一個上鎖、解鎖的過程,不過C++中要locked和unlocked,而Java中直接synchornized(物件)就可以了。

        synchronized(物件)

        {

         }

 

         public synchronized  void  compared(parameter)

        {

         }


(2)deadLock(死鎖):

   Java存在synchornized機制(互斥鎖),同時也會帶來deadlock,不合理的時用synchornized就容易產生死鎖,導致執行緒永久等待。

1.鎖中再加鎖人分離:你在上廁所,外面卻有個你在廁所外敲門。

        synchronized(物件data)

        {        

                  synchronized(同一物件da'ta)

                 {

                 }

         }

2.互相鎖住定終生:我把一號門鎖了敲二號門,他把二號門鎖了敲一號門。我他隔門相對定終身。

      //Thread1中    

       synchronized(物件data1)

        {        

                  synchronized(物件data2)

                 {

                 }

         }

//Thread2中

synchronized(物件data2)

        {        

                  synchronized(物件data1)

                 {

                 }

         }


(3)通知機制(notify/wait):

顧名思義就是通知的味道。通知機制是為了保證資料被存入後被即使的取出,防止資料積累帶來不好的影響。

為了即使取走資料有兩種方法:輪詢機制(讓取東西的執行緒不斷的檢查,但可能空跑一趟)

                                                   通知機制(當存入資料後通知另一個執行緒來取資料)

    兩種機制特點 :     輪詢機制:實現比較簡單,但效率低。

                                    通知機制:實現起來比較複雜,但效率高。

notify/wait實現:

wait / notify 是Object類的方法 
 
發出通知

 synchronized (basket)  

{  

            basket.add(egg);  

            basket.notify();    //發出通知

}

 

等待通知  

synchronized (basket)

 {        

               try  { basket.wait(); }            //等待接收通知

               catch (InterruptedException e) {}  

               if(basket.size() > 0)

                      egg = basket.remove(0);

  }  

注:notify/wait機制必須在同一synchornized下進行(notify/wait與synchornized作用物件一樣),這是Java特定的機制,必須這麼使用(官方說法是,在 wait/notify之前,必須先成為該物件的監視者Monitor) 。儘量將耗時且與notify/wait作用物件無關的處理放在notify/wait外,這樣可以大大節省處理時間。

(謝謝觀看,歡迎點評和糾錯)