1. 什麼是原子操作?在Java Concurrency API中有哪些原子類(atomic classes)?
原子操作是指一個不受其他操作影響的操作任務單元。原子操作是在多線程環境下避免數據不一致必須的手段。
int++並不是一個原子操作,所以當一個線程讀取它的值並加1時,另外一個線程有可能會讀到之前的值,這就會引發錯誤。
為了解決這個問題,必須保證增加操作是原子的,在JDK1.5之前我們可以使用同步技術來做到這一點。到JDK1.5,java.util.concurrent.atomic包提供了int和long類型的裝類,它們可以自動的保證對於他們的操作是原子的並且不需要使用同步。可以閱讀這篇文章來了解Java的atomic類。
2. Java Concurrency API中的Lock介面(Lock interface)是什麼?對比同步它有什麼優勢?
Lock介面比同步方法和同步塊提供了更具擴展性的鎖操作。他們允許更靈活的結構,可以具有完全不同的性質,並且可以支持多個相關類的條件對象。
它的優勢有:
可以使鎖更公平
可以使線程在等待鎖的時候響應中斷
可以讓線程嘗試獲取鎖,並在無法獲取鎖的時候立即返回或者等待一段時間
可以在不同的範圍,以不同的順序獲取和釋放鎖
3. 什麼是Executors框架?
Executor框架同java.util.concurrent.Executor 介面在Java 5中被引入。Executor框架是一個根據一組執行策略調用,調度,執行和控制的非同步任務的框架。
無限制的創建線程會引起應用程序內存溢出。所以創建一個線程池是個更好的的解決方案,因為可以限制線程的數量並且可以回收再利用這些線程。利用Executors框架可以非常方便的創建一個線程池,閱讀這篇文章可以了解如何使用Executor框架創建一個線程池。
4. 什麼是阻塞隊列?如何使用阻塞隊列來實現生產者-消費者模型?
java.util.concurrent.BlockingQueue的特性是:當隊列是空的時,從隊列中獲取或刪除元素的操作將會被阻塞,或者當隊列是滿時,往隊列里添加元素的操作會被阻塞。
阻塞隊列不接受空值,當你嘗試向隊列中添加空值的時候,它會拋出NullPointerException。
阻塞隊列的實現都是線程安全的,所有的查詢方法都是原子的並且使用了內部鎖或者其他形式的併發控制。
BlockingQueue介面是java collections框架的一部分,它主要用於實現生產者-消費者問題。
5. 什麼是Callable和Future?
Java 5在concurrency包中引入了java.util.concurrent.Callable 介面,它和Runnable介面很相似,但它可以返回一個對象或者拋出一個異常。
Callable介面使用泛型去定義它的返回類型。Executors類提供了一些有用的方法去在線程池中執行Callable內的任務。由於Callable任務是并行的,我們必須等待它返回的結果。
java.util.concurrent.Future對象為我們解決了這個問題。在線程池提交Callable任務后返回了一個Future對象,使用它我們可以知道Callable任務的狀態和得到Callable返回的執行結果。Future提供了get方法讓我們可以等待Callable結束並獲取它的執行結果。
6. 什麼是FutureTask?
FutureTask是Future的一個基礎實現,我們可以將它同Executors使用處理非同步任務。通常我們不需要使用FutureTask類,單當我們打算重寫Future介面的一些方法並保持原來基礎的實現是,它就變得非常有用。我們可以僅僅繼承於它並重寫我們需要的方法。閱讀Java FutureTask例子,學習如何使用它。
7.什麼是併發容器的實現?
Java集合類都是快速失敗的,這就意味著當集合被改變且一個線程在使用迭代器遍歷集合的時候,迭代器的next方法將拋出ConcurrentModificationException異常。
併發容器支持併發的遍歷和併發的更新。
主要的類有ConcurrentHashMap,CopyOnWriteArrayList和CopyOnWriteArraySet,閱讀這篇文章了解如何避免ConcurrentModificationException。
8. Executors類是什麼?
Executors為Executor,ExecutorService,ScheduledExecutorService,ThreadFactory和Callable類提供了一些工具方法。
Executors可以用於方便的創建線程池。