Java並發必須知道的零碎知識(二)__Java

來源:互聯網
上載者:User
1.  Wait/notify與Condition.await /condition.signal /Condition.signalAll

一個Condition和一個Lock關聯在一起,就想一個條件隊列和一個內建鎖相關聯一樣。要建立一個Condition,可以在相關聯的Lock上調用Lock.newCondition方法。正如Lock比內建加鎖提供了更為豐富的功能,Condition同樣比內建條件隊列提供了更豐富的功能:在每個鎖上可存在多個等待、條件等待可以是可中斷的或者不可中斷的、基於時限的等待,以及公平的或非公平的隊列操作。與內建條件隊列不同的是,對於每個Lock,可以有任意數量的Condition對象。Condition對象繼承了相關的Lock對象的公平性,對於公平的鎖,線程會依照FIFO順序從Condition.await中釋放。

注意:在Condition對象中,與wait,notify和notifyAll方法對於的分別是await,signal,signalAll。但是,Condition對Object進行了擴充,因而它也包含wait和notify方法。一定要確保使用的版本——await和signal.

Condition的作用是對鎖進行更精確的控制。Condition中的await()方法相當於Object的wait()方法,Condition中的signal()方法相當於Object的notify()方法,Condition中的signalAll()相當於Object的notifyAll()方法。不同的是,Object中的wait(),notify(),notifyAll()方法是和"同步鎖"(synchronized關鍵字)捆綁使用的;而Condition是需要與"互斥鎖"/"共用鎖定"捆綁使用的。


2.  如何避免死結

死結是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。這是一個嚴重的問題,因為死結會讓你的程式掛起無法完成任務,死結的發生必須滿足以下四個條件:

 

    互斥條件:一個資源每次只能被一個進程使用。

    請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。

    不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。

    迴圈等待條件:若干進程之間形成一種頭尾相接的迴圈等待資源關係。

 

避免死結最簡單的方法就是阻止迴圈等待條件,將系統中所有的資源設定標誌位、排序,規定所有的進程申請資源必須以一定的順序(升序或降序)做操作來避免死結。


3.  有三個線程T1,T2,T3,怎麼確保它們按順序執行

在多線程中有多種方法讓線程按特定順序執行,你可以用線程類的join()方法在一個線程中啟動另一個線程,另外一個線程完成該線程繼續執行。為了確保三個線程的順序你應該先啟動最後一個(T3調用T2,T2調用T1),這樣T1就會先完成而T3最後完成。

 

如果一個線程A執行了thread.join()語句,其含義是:當前線程A等待thread線程終止之後才從thread.join()返回。join與synchronized的區別是:join在內部使用wait()方法進行等待,而synchronized關鍵字使用的是“對象監視器”做為同步。

join提供了另外兩種實現方法:join(long millis)和join(long millis, int nanos),至多等待多長時間而退出等待(釋放鎖),退出等待之後還可以繼續運行。內部是通過wait方法來實現的。


4.  如果你提交任務時,線程池隊列已滿。會時發會生什麼

這個問題問得很狡猾,許多程式員會認為該任務會阻塞直到線程池隊列有空位。事實上如果一個任務不能被調度執行那麼ThreadPoolExecutor’s submit()方法將會拋出一個RejectedExecutionException異常。


5.  Java線程池中submit() 和 execute()方法有什麼區別

兩個方法都可以向線程池提交任務,execute()方法的傳回型別是void,它定義在Executor介面中,而submit()方法可以返回持有計算結果的Future對象,它定義在ExecutorService介面中,它擴充了Executor介面,其它線程池類像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有這些方法。


6.  如何在Java中建立Immutable對象。

這個問題看起來和多線程沒什麼關係, 但不變性有助於簡化已經很複雜的並發程式。Immutable對象可以在沒有同步的情況下共用,降低了對該對象進行並發訪問時的同步化開銷。可是Java沒有@Immutable這個註解符,要建立不可變類,要實現下面幾個步驟:通過構造方法初始化所有成員、對變數不要提供setter方法、將所有的成員聲明為私人的,這樣就不允許直接存取這些成員、在getter方法中,不要直接返回對象本身,而是複製對象,並返回對象的拷貝。


7.  yield方法

yield()方法的作用是放棄當前的CPU資源,將它讓給其他的任務去佔用CPU執行時間。但放棄時間不確定,有可能剛剛放棄,馬上又獲得CPU時間片。這裡需要注意的是yield()方法和sleep方法一樣,線程並不會讓出鎖,和wait不同。


8.  守護線程

Java中有兩種線程,一種是使用者線程,另一種是守護線程。當進程中不存在非守護線程了,則守護線程自動銷毀。通過setDaemon(true)設定線程為後台線程。注意thread.setDaemon(true)必須在thread. Start()之前設定,否則會報IllegalThreadStateException異常;在Daemon線程中產生的新線程也是Daemon的;在使用ExecutorSerice等多線程架構時,會把守護線程轉換為使用者線程,並且也會把優先順序設定為Thread.NORM_PRIORITY。在構建Daemon線程時,不能依靠finally塊中的內容來確保執行關閉或清理資源的邏輯。


9.  安全執行緒的非阻塞隊列

非阻塞隊列有ConcurrentLinkedQueue, ConcurrentLinkedDeque。元素不能為null。以ConcurrentLinkedQueue為例,有頭head和尾tail兩個指標,遵循FIFO的原則進行入隊和出隊,方法有add(E e), peek()取出不刪除, poll()取出刪除, remove(Object o),size(), contains(Objecto), addAll(Collection c), isEmpty()。ConcurrentLinkedDeque是雙向隊列,可以在頭和尾兩個方向進行相應的操作。


10. 阻塞隊列

ArrayBlockingQueue:一個由數組結構組成的有界阻塞隊列。

LinkedeBlockingQueue:一個有鏈表結構組成的有界阻塞隊列。

PriorityBlockingQueue:一個支援優先順序排序的無界阻塞隊列

DelayQueue:一個使用優先順序隊列實現的無界阻塞隊列。

SynchronousQueue:一個不儲存元素的阻塞隊列。

LinkedTransferQueue:一個由鏈表結構組成的無界阻塞隊列。

LinkedBlockingDeque:一個由鏈表結構組成的雙向阻塞隊列。

見串連:http://www.cnblogs.com/dolphin0520/p/3932906.html


11. Happens-Before規則

程式順序規則:如果程式中操作A在操作B之前,那麼線上程中A操作將在B操作之前。

監視器鎖規則:一個unlock操作現行發生於後面對同一個鎖的lock操作。

volatile變數規則:對一個volatile變數的寫操作先行發生於後面對這個變數的讀操作,這裡的“後面”同樣是指時間上的先後順序。

線程啟動規則:Thread對象的start()方法先行發生於此線程的每一個動作。

線程終止規則:線程的所有操作都先行發生於對此線程的終止檢測,我們可以通過Thread.join()方法結束、Thread.isAlive()的傳回值等於段檢測到線程已經終止執行。

線程中斷規則:線程interrupt()方法的調用先行發生於被中斷線程的代碼檢測到中斷事件的發生。

終結器規則:對象的建構函式必須在啟動該對象的終結器之前執行完成。

傳遞性:如果操作A先行發生於操作B,操作B先行發生於操作C,那就可以得出操作A先行發生於操作C的結論。

  12. 如何避免死結

死結是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,他們都將無法推進下去。這是一個嚴重的問題,因為死結會讓你的程式掛起無法完成任務,死結的發生必須滿足一下4個條件:

互斥條件:一個資源每次只能被一個進程使用。

請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。

不剝奪條件:進程已獲得的資源,在未使用完之前,不能強行剝奪。

迴圈等待條件:若干進程之間形成一種頭尾相接的迴圈等待資源關係。

避免死結最簡單的方法就是阻止迴圈等待條件,將系統中所有的資源設定標誌位、排序,規定所有的進程申請資源必須以一定的順序做操作來避免死結。


1.  多線程之間如何進行資訊互動

 

2.  如何停止一個線程

 

3.  什麼是安全執行緒、如何保證

 

4.  Sleep和wait的區別


聯繫我們

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