1. 程式人生 > >面試-阻塞佇列及執行緒池

面試-阻塞佇列及執行緒池

16  阻塞佇列

  阻塞佇列與普通佇列的區別在於:當佇列是空的時,從佇列中獲取元素的操作將會被阻塞,或者當佇列是滿時,往佇列裡新增元素的操作會被阻塞。

17  執行緒池

執行緒池(ThreadPool)對於限制應用程式中同一時刻執行的執行緒數很有用。因為每啟動一個新執行緒都會有相應的效能開銷,每個執行緒都需要給棧分配一些記憶體等等。

18  剖析同步器

大部分同步器都是用來保護某個區域(臨界區)的程式碼,這些程式碼可能會被多執行緒併發訪問。要實現這個目標,同步器一般要支援下列功能

狀態:同步器中的狀態是用來確定某個執行緒是否有訪問許可權。在Lock中,狀態是boolean型別的,表示當前Lock物件是否處於鎖定狀態。在BoundedSemaphore

中,內部狀態包含一個計數器(int型別)和一個上限(int型別),分別表示當前已經獲取的許可數和最大可獲取的許可數。BlockingQueue的狀態是該佇列中元素列表以及佇列的最大容量。

  訪問條件:訪問條件決定呼叫test-and-set-state方法的執行緒是否可以對狀態進行設定。訪問條件一般是基於同步器狀態的。通常是放在一個while迴圈裡,以避免虛假喚醒問題。訪問條件的計算結果要麼是true要麼是false。Lock中的訪問條件只是簡單地檢查isLocked的值。根據執行的動作是“獲取”還是“釋放”,BoundedSemaphore中實際上有兩個訪問條件。如果某個執行緒想“獲取”許可,將檢查signals變數是否達到上限;如果某個執行緒想“釋放”許可,將檢查signals變數是否為0。

這裡有兩個來自Lock和BoundedSemaphore的程式碼片段,它們都有訪問條件。注意觀察條件是怎樣在while迴圈中檢查的。

  狀態變化: 一旦一個執行緒獲得了臨界區的訪問許可權,它得改變同步器的狀態,讓其它執行緒阻塞,防止它們進入臨界區。換而言之,這個狀態表示正有一個執行緒在執行臨界區的程式碼。其它執行緒想要訪問臨界區的時候,該狀態應該影響到訪問條件的結果。

Lock中,通過程式碼設定isLocked= true來改變狀態,在訊號量中,改變狀態的是signals–或signals++;

  通知策略:一旦某個執行緒改變了同步器的狀態,可能需要通知其它等待的執行緒狀態已經變了。因為也許這個狀態的變化會讓其它執行緒的訪問條件變為true。

通知策略通常分為三種:

1、通知所有等待的執行緒:所有等待的執行緒都呼叫的同一個物件上的wait()方法,某個執行緒想要通知它們只需在這個物件上呼叫notifyAll()方法。

2、通知N個等待執行緒中的任意一個:只需將notifyAll()呼叫換成notify()即可。呼叫notify方法沒辦法確定喚醒的是哪一個執行緒,也就是“等待執行緒中的任意一個”。

3、通知N個等待執行緒中的某個指定的執行緒:有時候可能需要通知指定的執行緒而非任意一個等待的執行緒。例如,如果你想保證執行緒被通知的順序與它們進入同步塊的順序一致,或按某種優先順序的順序來通知。想要實現這種需求,每個等待的執行緒必須在其自有的物件上呼叫wait()。當通知執行緒想要通知某個特定的等待執行緒時,呼叫該執行緒自有物件的notify()方法即可。飢餓和公平中有這樣的例子。

  Test-and-Set方法:同步器中最常見的有兩種型別的方法,test-and-set是第一種(set是另一種)。Test-and-set的意思是,呼叫這個方法的執行緒檢查訪問條件,如若滿足,該執行緒設定同步器的內部狀態來表示它已經獲得了訪問許可權。

狀態的改變通常使其它試圖獲取訪問許可權的執行緒計算條件狀態時得到false的結果,但並不一定總是如此。例如,在讀寫鎖中,獲取讀鎖的執行緒會更新讀寫鎖的狀態來表示它獲取到了讀鎖,但是,只要沒有執行緒請求寫鎖,其它請求讀鎖的執行緒也能成功。

test-and-set很有必要是原子的,也就是說在某個執行緒檢查和設定狀態期間,不允許有其它執行緒在test-and-set方法中執行。

test-and-set方法的程式流通常遵照下面的順序:

1、如有必要,在檢查前先設定狀態

2、檢查訪問條件

3、如果訪問條件不滿足,則等待

4、如果訪問條件滿足,設定狀態,如有必要還要通知等待執行緒

  Set方法:set方法是同步器中常見的第二種方法。set方法僅是設定同步器的內部狀態,而不先做檢查。set方法的一個典型例子是Lock類中的unlock()方法。持有鎖的某個執行緒總是能夠成功解鎖,而不需要檢查該鎖是否處於解鎖狀態。

set方法的程式流通常如下:

1、設定內部狀態

2、通知等待的執行緒

http://ifeve.com/anatomy-of-a-synchronizer/