Java读书笔记(4)-多线程(二)
2016-1-2
線程通信
-
傳統(tǒng)的線程通信
-
Object類提供了wait(),notify()和notifyAll三個(gè)方法
-
適用情況:synchronized修飾的同步方法或者synchronized方法
-
wait():導(dǎo)致當(dāng)前線程等待,直到其他線程調(diào)用該同步監(jiān)視器的notify()或notifyAll方法來喚醒該線程,調(diào)用wait方法后本線程會(huì)釋放對同步監(jiān)視器的鎖定
-
notify():喚醒在此同步監(jiān)視器上等待的單個(gè)線程。如果有多個(gè)線程在等待,則隨機(jī)喚醒其中一個(gè)
-
notifyAll():喚醒在此同步監(jiān)視器上等待的所有線程
-
-
使用Condition控制線程通信
-
適用于使用Lock對象來同步的場景,Condition實(shí)例被綁定在一個(gè)Lock對象
-
Lock替代了同步方法或同步代碼塊,Condition替代了同步監(jiān)視器的功能
-
await(),signal(),signalAll()
-
private final Lock lock=new ReentrantLock();
-
private final Condition cond=lock.newCondition();
-
cond.await()
-
cond.signalAll()
-
-
使用阻塞隊(duì)列(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)和未處理的異常
-
程序可以直接以組為單位控制線程
-
線程運(yùn)行途中不能更改所屬線程組
-
ThreadGroup:activeCount(), interrupt(), isDaemon(), setDaemon(), setMaxPriority()
-
ThreadGroup內(nèi)還定義了一個(gè)很有用的方法:void uncaughtException(Thread t,Throwable e), 可以處理線程組內(nèi)任意線程所拋出的異常
-
使用catch捕獲異常時(shí),異常不會(huì)傳播給上一級(jí)調(diào)用者;但是使用異常處理器對異常進(jìn)行處理后,異常依然會(huì)傳播給上一級(jí)調(diào)用者
-
線程池
-
當(dāng)程序中需要?jiǎng)?chuàng)建大量生存期很短暫的線程時(shí),應(yīng)該考慮使用線程池。線程池在系統(tǒng)啟動(dòng)時(shí)即創(chuàng)建大量空閑的線程
-
Java5實(shí)現(xiàn)的線程池
-
返回一個(gè)ExecutorService對象,該對象代表一個(gè)線程池:newCachedThreadPool()newFixedThreadPool(int nThreads),newSingleThreadExecutor()
-
new ScheduledThreadPool(int corePoolSize),new SingleThreadScheduledExecutor()
-
使用線程池來執(zhí)行線程任務(wù)的步驟:
-
調(diào)用Executors類的靜態(tài)工廠方法來創(chuàng)建一個(gè)ExecutorService對象,該對象代表一個(gè)線程池;
-
創(chuàng)建Runnable實(shí)現(xiàn)類或Callable實(shí)現(xiàn)類的實(shí)例,作為線程執(zhí)行任務(wù);
-
調(diào)用ExecutorService對象的submit()方法來提交Runnable實(shí)例或者Callable實(shí)例;
-
任務(wù)執(zhí)行完畢,最后關(guān)閉線程池shutdown()。
-
Java7新增的ForkJoinPool
-
充分利用多CPU,多核CPU的性能優(yōu)勢
-
將一個(gè)任務(wù)拆分成多個(gè)“小任務(wù)”并行計(jì)算,再把多個(gè)小任務(wù)的結(jié)果合并成總的計(jì)算結(jié)果
-
ForkJoinPool是ExecutorService的實(shí)現(xiàn)類,因此是一種特殊的線程池
-
創(chuàng)建了ForkJoinPool實(shí)例之后,就可以調(diào)用ForkJoinPool的submit(ForkJoinTask task)或者invoke(ForkJoinTask task)方法來執(zhí)行指定任務(wù)了。其中ForkJoinTask代表一個(gè)可以并行,合并的任務(wù)。ForkJoinTask是一個(gè)抽象類,它還有兩個(gè)抽象子類:RecursiveAction和RecursiveTask。其中RecursiveTask代表有返回值的任務(wù),而RecursiveAction代表沒有返回值的任務(wù)。
線程相關(guān)類
-
ThreadLocal類
-
代表一個(gè)線程局部變量,通過把數(shù)據(jù)放在ThreadLocal中就可以讓每個(gè)線程創(chuàng)建一個(gè)該變量的副本
-
在編寫多線程代碼時(shí),可以把不安全的整個(gè)變量封裝進(jìn)ThreadLocal,或者把對象與線程相關(guān)的狀態(tài)使用ThreadLocal保存
-
ThreadLocal類與線程同步機(jī)制面向的問題領(lǐng)域是不同的
-
如果多個(gè)資源之間需要共享資源,以實(shí)現(xiàn)線程通信,則使用同步機(jī)制;如果僅僅只是隔離多個(gè)線程之間的沖突,則使用ThreadLocal
-
-
包裝線程不安全的集合
-
可以使用Collections提供的靜態(tài)方法把這些集合包裝成線程安全的集合。
-
<T> Collection<T> synchronizedCollections(Collection<T> c):返回指定collection對應(yīng)的線程安全的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)
-
-
如果需要把某個(gè)集合包裝成線程安全的集合,則應(yīng)該在創(chuàng)建之后立即包裝
HashMap m=Collections.synchronizedMap(new HashMap());
線程安全的集合類
-
java.util.concurrent包
-
支持高效并發(fā)訪問的集合接口和實(shí)現(xiàn)類
-
以Concurrent開頭的集合類:支持并發(fā)訪問的集合
-
以CopyOnWrite開頭的集合類:適合讀取操作遠(yuǎn)遠(yuǎn)大于寫入操作的場景,如緩存等
轉(zhuǎn)載于:https://www.cnblogs.com/hust_wsh/p/5095858.html
總結(jié)
以上是生活随笔為你收集整理的Java读书笔记(4)-多线程(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lamp环境搭建经验总结
- 下一篇: java如何得到GET和POST请求UR