並發編程學習(二)
對象發生變化鎖失效,對象內的屬性改變,鎖不會失效。
ConcurrentModificationException出現的原因是因為以前的容器沒有考慮到並發情況下讀取的時候刪除元素而引起的。
wait/notify:
wait和notify是Object類的方法,wait會釋放鎖,notify不釋放鎖。這兩個必須配合synchronized一同使用。
並發容器:
ConcurrentHashMap:
內部使用段(segment)來表示這些不同部分,每個段其實就是一個小的hashtable,各自有鎖,共分為16個段,最高支持16個線程,代碼中大多共享變量使用volatile。
CopyOnWrite:
寫時復制,是在寫完
ConcurrentLinkedQueue:
是一個適用於高並發場景下的隊列,通過無鎖的方式,實現了高並發狀態下的高性能,性能好於blockingQueue,隊列無界,先進先出,不允許有null值。
add()和offer()都是加入元素,poll()和peek()都是取頭部數據,區別在於前都會刪除元素,後者不會。
ArrayBlockingQueue:
必須要定義長度,也叫有界隊列。
LinkedBlockingQueue:
無界隊列,內部采用分離鎖(讀寫分離)。適用於高並發。
SynchronousQueue:
一種沒有緩沖的隊列,生產者產生的數據直接被消費者消費。
PriorityBlockingQueue:
基於優先級的阻塞隊列。
DelayQueue:
帶有延遲時間的Queue。
Executor框架:
newFixedThreadPool():固定數量的線程池,有任務提交就執行,沒有線程空閑就暫緩在一個任務隊列中。
newSingleThreadPool():創建一個線程的線程池,若空閑就執行,沒有就存在任務隊列中。
newCachedThreadPool():返回一個根據實際情況調整線程個數的線程池,不限制最大線程數量,如果沒有任務60s就回收。
newScheduledThreadPool():返回一個ScheduledExecutorService對象,可以指定線程數量。可做定時job。
線程池底層是調用ThreadPoolExecutor()來實現的。
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory); }
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));//父類也是ThreadPoolExecutor
}
ThreadPoolExecutor方法內參數說明:
public ThreadPoolExecutor(int corePoolSize,//核心線程數
int maximumPoolSize,//最大線程數
long keepAliveTime, //空閑存活時間
TimeUnit unit, //時間單位
BlockingQueue<Runnable> workQueue,//任務隊列
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
並發編程學習(二)