Java多執行緒技術中所有方法的詳細解析

小科學家發表於2009-04-13
  一、run()和start()

  這兩個方法應該都比較熟悉,把需要並行處理的程式碼放在run()方法中,start()方法啟動執行緒將自動呼叫 run()方法,這是由Java的記憶體機制規定的。並且run()方法必須是public訪問許可權,返回值型別為void.

  二、關鍵字Synchronized

  這個關鍵字用於保護共享資料,當然前提是要分清哪些資料是共享資料。每個物件都有一個鎖標誌,當一個執行緒訪問該物件時,被Synchronized修飾的資料將被“上鎖”,阻止其他執行緒訪問。當前執行緒訪問完這部分資料後釋放鎖標誌,其他執行緒就可以訪問了。

以下是引用片段:
public ThreadTest implements Runnable
  {
  public synchronized void run(){
  for(int i=0;i<10;i++)
  {
  System.out.println(" " + i);
  }
  }
  public static void main(String[] args)
  {
  Runnable r1 = new ThreadTest();
  Runnable r2 = new ThreadTest();
  Thread t1 = new Thread(r1);
  Thread t2 = new Thread(r2);
  t1.start();
  t2.start();
  }
  }

 

  以上這段程式中的 i 變數並不是共享資料,也就是這裡的Synchronized關鍵字並未起作用。因為t1,t2兩個執行緒是兩個物件(r1,r2)的執行緒。不同的物件其資料是不同的,所以r1和r2兩個物件的i變數是並不是共享資料。

  當把程式碼改成如下:Synchronized關鍵字才會起作用

以下是引用片段:
 Runnable r = new ThreadTest();
  Thread t1 = new Thread(r);
  Thread t2 = new Thread(r);
  t1.start();
  t2.start();
  三、sleep()

  使當前執行緒(即呼叫該方法的執行緒)暫停執行一段時間,讓其他執行緒有機會繼續執行,但它並不釋放物件鎖。也就是如果有Synchronized同步塊,其他執行緒仍然不同訪問共享資料。注意該方法要捕獲異常

  比如有兩個執行緒同時執行(沒有Synchronized),一個執行緒優先順序為MAX_PRIORITY,另一個為MIN_PRIORITY,如果沒有Sleep()方法,只有高優先順序的執行緒執行完成後,低優先順序的執行緒才能執行;但當高優先順序的執行緒sleep(5000)後,低優先順序就有機會執行了。

  總之,sleep()可以使低優先順序的執行緒得到執行的機會,當然也可以讓同優先順序、高優先順序的執行緒有執行的機會。

  四、join()

  join()方法使呼叫該方法的執行緒在此之前執行完畢,也就是等待呼叫該方法的執行緒執行完畢後再往下繼續執行。注意該方法也要捕獲異常。

  五、yield()

  它與sleep()類似,只是不能由使用者指定暫停多長時間,並且yield()方法只能讓同優先順序的執行緒有執行的機會。

  六、wait()和notify()、notifyAll()

  這三個方法用於協調多個執行緒對共享資料的存取,所以必須在Synchronized語句塊內使用這三個方法。前面說過Synchronized 這個關鍵字用於保護共享資料,阻止其他執行緒對共享資料的存取。但是這樣程式的流程就很不靈活了,如何才能在當前執行緒還沒退出Synchronized資料塊時讓其他執行緒也有機會訪問共享資料呢?此時就用這三個方法來靈活控制。

  wait()方法使當前執行緒暫停執行並釋放物件鎖標誌,讓其他執行緒可以進入Synchronized資料塊,當前執行緒被放入物件等待池中。當呼叫 notify()方法後,將從物件的等待池中移走一個任意的執行緒並放到鎖標誌等待池中,只有

  鎖標誌等待池中的執行緒能夠獲取鎖標誌;如果鎖標誌等待池中沒有執行緒,則notify()不起作用。

  notifyAll()則從物件等待池中移走所有等待那個物件的執行緒並放到鎖標誌等待池中。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/21359667/viewspace-588793/,如需轉載,請註明出處,否則將追究法律責任。

相關文章