Java MultiThread學習筆記

來源:互聯網
上載者:User

1. synchronized function

用法:  synchronized foo() {}


字面意思是讓一個函數塊保持同步,但是保持和誰同步呢? 答案是和另一個或一些加了synchronized 關鍵字的函數,它能保證在這個對象內,所有加synchronized 的函數在同一時間只有一個在運行,並只運行在某一個線程中,假如這些函數可能會被運行在不同的線程,又要同時訪問同一個資源,那麼就可以用它了。 (這段話不知道我說對了沒有)Only
one thread at a time can call a synchronized method for a particular object (although that thread can call more than one of the object’s synchronized methods). Objects
can have synchronized methods that prevent threads from accessing that object until the synchronization lock is released。


例如 :

synchronized foo0() { A;}

synchronized foo1() { B;}

A, B 之間如果想同步,(即A執行時B不能執行,B執行時A不能執行),需要把兩個函數都加上synchronized,只加一個相當於沒加。

If you synchronize only one of the methods, then the other is free to ignore the object lock and can
be called with impunity. This is an important point: Every method that accesses a critical shared resource must be synchronized or it won’t work
right. 

2. synchronized object 
用法:

synchronized(syncObject) {  // This code can be accessed   // by only one thread at a time}

字面意思是同步一個對象,實際上是用一個對象當作鎖,來建立一個臨界區(Critical section),臨界區內代碼同一時間只能由一個線程來訪問,進一步說,syncObject只有一把鑰匙,在一個時間點上,哪個線程拿到這把鑰匙,哪個線程就可以進入臨界區,執行完後返回鑰匙給syncObject,其它沒鑰匙的線程等鑰匙空閑了之後,再由系統決定把鑰匙給誰。
注意:synchronized 方法濫用會降低系統效能,因為進入、退出同步方法(塊)時會多一些操作,盡量少用。
另外, 在非同步線程中訪問另一個線程的ArrayList,應該複製一份:

    ArrayList lv = null;    // Make a shallow copy of the List in case     // someone adds a listener while we're     // calling listeners:    synchronized(this) {      lv = (ArrayList)actionListeners.clone();    }

其中,synchronized(this) {}相當於synchronized foo() {}的效果,即用當前對象的大鎖來同步。PS synchronized  不會被子類繼承。
線程基本知識:線程的四種狀態:1 新的2 可啟動並執行 Runnable 隨時可能被運行,有時運行,有時不運行3 死的 Dead 通常發生在run{}退出後4 阻塞的 Blocked
3 How to BLOCK a Thread? 多線程的重點是如何去阻塞一個線程?目的是利用阻塞來實現某種程度的同步。阻塞有兩種:Sleep和 wait/notify。區別:Sleep不釋放當前線程對象的鎖,而wait釋放當前線程的鎖,由notify來重新拿回鎖,拿回鎖之後,執行wait()之後的程式。使用wait/notify的注意事項:因為這兩個函數要操作當前對象的鎖,不能做“無米之炊”,操作鎖之前要拿到這把鎖,然而什麼時機才能確保我們手中有鎖呢?答案是在synchronized 同步塊(方法)中,其中同步塊即synchronized(Object o){},可以確保拿到Object的鎖, 而同步方法即  synchronized void foo() {}, 可以確保拿到些函數所處對象的鎖,總結以上的經驗, 應該這樣來調用wait()/notify():

synchronized (object) {   ...   try {     object.wait();   } catch(InterruptedException e) {   }   //object.notify();   ...}synchronized void foo () {   ...   try {      wait(); //Current thread wait();   } catch(InterruptedException e) {   }   //object.notify();   ...}

注意catch線程中斷的異常。
4 死結當一個線程A因為另一個線程B而阻塞,而線程B因為線程C阻塞,C又因為A阻塞,這樣的無限迴圈造成死結。寫程式的時候一定要小心,因為一旦出現死結,你將會“死”很久去調試。
5 退出線程的方法5.1 Use stop mark:

  public void terminate() { stop = true; }  public void run() {    while (!stop) {    ......    }}
5.2    interrupt():

// blocked is a thread
if(blocked == null) return;          Thread remove = blocked;          blocked = null; // to release it          remove.interrupt();
Note:開太多的線程可能會導致JVM停滯,能用線性地方就不用多線程,線性過程比多線程快!線程一般用於提高使用者響應速度,網路下載等。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.