2016-1-2java
線程通訊緩存
傳統的線程通訊安全
Object類提供了wait(),notify()和notifyAll三個方法多線程
適用狀況:synchronized修飾的同步方法或者synchronized方法併發
wait():致使當前線程等待,直到其餘線程調用該同步監視器的notify()或notifyAll方法來喚醒該線程,調用wait方法後本線程會釋放對同步監視器的鎖定性能
notify():喚醒在此同步監視器上等待的單個線程。若是有多個線程在等待,則隨機喚醒其中一個spa
notifyAll():喚醒在此同步監視器上等待的全部線程線程
使用Condition控制線程通訊對象
適用於使用Lock對象來同步的場景,Condition實例被綁定在一個Lock對象接口
Lock替代了同步方法或同步代碼塊,Condition替代了同步監視器的功能
await(),signal(),signalAll()
private final Lock lock=new ReentrantLock();
private final Condition cond=lock.newCondition();
cond.await()
cond.signalAll()
使用阻塞隊列(BlockingQueue)控制線程通訊
add(E e), off(E e), put(E e)
remove(), poll(), take()
element(), peek()
ArrayBlockinQueue, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue, DelayQueue
BlockingQueue<Stirng> bq=new ArrayBlockingQueue<>(2);
bg.put(「Java」)
線程組(ThreadGroup)和未處理的異常
程序能夠直接以組爲單位控制線程
線程運行途中不能更改所屬線程組
ThreadGroup:activeCount(), interrupt(), isDaemon(), setDaemon(), setMaxPriority()
ThreadGroup內還定義了一個頗有用的方法:void uncaughtException(Thread t,Throwable e), 能夠處理線程組內任意線程所拋出的異常
使用catch捕獲異常時,異常不會傳播給上一級調用者;可是使用異常處理器對異常進行處理後,異常依然會傳播給上一級調用者
線程池
當程序中須要建立大量生存期很短暫的線程時,應該考慮使用線程池。線程池在系統啓動時即建立大量空閒的線程
Java5實現的線程池
返回一個ExecutorService對象,該對象表明一個線程池:newCachedThreadPool()newFixedThreadPool(int nThreads),newSingleThreadExecutor()
new ScheduledThreadPool(int corePoolSize),new SingleThreadScheduledExecutor()
使用線程池來執行線程任務的步驟:
調用Executors類的靜態工廠方法來建立一個ExecutorService對象,該對象表明一個線程池;
建立Runnable實現類或Callable實現類的實例,做爲線程執行任務;
調用ExecutorService對象的submit()方法來提交Runnable實例或者Callable實例;
任務執行完畢,最後關閉線程池shutdown()。
Java7新增的ForkJoinPool
充分利用多CPU,多核CPU的性能優點
將一個任務拆分紅多個「小任務」並行計算,再把多個小任務的結果合併成總的計算結果
ForkJoinPool是ExecutorService的實現類,所以是一種特殊的線程池
建立了ForkJoinPool實例以後,就能夠調用ForkJoinPool的submit(ForkJoinTask task)或者invoke(ForkJoinTask task)方法來執行指定任務了。其中ForkJoinTask表明一個能夠並行,合併的任務。ForkJoinTask是一個抽象類,它還有兩個抽象子類:RecursiveAction和RecursiveTask。其中RecursiveTask表明有返回值的任務,而RecursiveAction表明沒有返回值的任務。
線程相關類
ThreadLocal類
表明一個線程局部變量,經過把數據放在ThreadLocal中就可讓每一個線程建立一個該變量的副本
在編寫多線程代碼時,能夠把不安全的整個變量封裝進ThreadLocal,或者把對象與線程相關的狀態使用ThreadLocal保存
ThreadLocal類與線程同步機制面向的問題領域是不一樣的
若是多個資源之間須要共享資源,以實現線程通訊,則使用同步機制;若是僅僅只是隔離多個線程之間的衝突,則使用ThreadLocal
包裝線程不安全的集合
可使用Collections提供的靜態方法把這些集合包裝成線程安全的集合。
<T> Collection<T> synchronizedCollections(Collection<T> c):返回指定collection對應的線程安全的collection;
static <T> List<T> synchronizedList(List<T> list)
static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)
static <T> Set<T> synchronizedSet(Set<T> s)
static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)
static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s)
若是須要把某個集合包裝成線程安全的集合,則應該在建立以後當即包裝
HashMap m=Collections.synchronizedMap(new HashMap());
線程安全的集合類
java.util.concurrent包
支持高效併發訪問的集合接口和實現類
以Concurrent開頭的集合類:支持併發訪問的集合
以CopyOnWrite開頭的集合類:適合讀取操做遠遠大於寫入操做的場景,如緩存等