Java讀書筆記(4)-多線程(二)

2016-1-2java

  1. 線程通訊緩存

    • 傳統的線程通訊安全

      • 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」)

  2. 線程組(ThreadGroup)和未處理的異常

      • 程序能夠直接以組爲單位控制線程

      • 線程運行途中不能更改所屬線程組

      • ThreadGroup:activeCount(), interrupt(), isDaemon(), setDaemon(), setMaxPriority()

      • ThreadGroup內還定義了一個頗有用的方法:void uncaughtException(Thread t,Throwable e), 能夠處理線程組內任意線程所拋出的異常

      • 使用catch捕獲異常時,異常不會傳播給上一級調用者;可是使用異常處理器對異常進行處理後,異常依然會傳播給上一級調用者

  3. 線程池

    • 當程序中須要建立大量生存期很短暫的線程時,應該考慮使用線程池。線程池在系統啓動時即建立大量空閒的線程

    • Java5實現的線程池

      • 返回一個ExecutorService對象,該對象表明一個線程池:newCachedThreadPool()newFixedThreadPool(int nThreads),newSingleThreadExecutor()

      • new ScheduledThreadPool(int corePoolSize),new SingleThreadScheduledExecutor()

      • 使用線程池來執行線程任務的步驟:

        1. 調用Executors類的靜態工廠方法來建立一個ExecutorService對象,該對象表明一個線程池;

        2. 建立Runnable實現類或Callable實現類的實例,做爲線程執行任務;

        3. 調用ExecutorService對象的submit()方法來提交Runnable實例或者Callable實例;

        4. 任務執行完畢,最後關閉線程池shutdown()

    • Java7新增的ForkJoinPool

      • 充分利用多CPU,多核CPU的性能優點

      • 將一個任務拆分紅多個「小任務」並行計算,再把多個小任務的結果合併成總的計算結果

      • ForkJoinPoolExecutorService的實現類,所以是一種特殊的線程池

      • 建立了ForkJoinPool實例以後,就能夠調用ForkJoinPoolsubmit(ForkJoinTask task)或者invoke(ForkJoinTask task)方法來執行指定任務了。其中ForkJoinTask表明一個能夠並行,合併的任務。ForkJoinTask是一個抽象類,它還有兩個抽象子類:RecursiveActionRecursiveTask。其中RecursiveTask表明有返回值的任務,而RecursiveAction表明沒有返回值的任務。

  4. 線程相關類

    • ThreadLocal

      • 表明一個線程局部變量,經過把數據放在ThreadLocal中就可讓每一個線程建立一個該變量的副本

      • 在編寫多線程代碼時,能夠把不安全的整個變量封裝進ThreadLocal,或者把對象與線程相關的狀態使用ThreadLocal保存

      • ThreadLocal類與線程同步機制面向的問題領域是不一樣的

      • 若是多個資源之間須要共享資源,以實現線程通訊,則使用同步機制;若是僅僅只是隔離多個線程之間的衝突,則使用ThreadLocal

    • 包裝線程不安全的集合

      • 可使用Collections提供的靜態方法把這些集合包裝成線程安全的集合。

        1. <T> Collection<T> synchronizedCollections(Collection<T> c):返回指定collection對應的線程安全的collection

        2. static <T> List<T> synchronizedList(List<T> list)

        3. static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)

        4. static <T> Set<T> synchronizedSet(Set<T> s)

        5. static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)

        6. static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s)

      • 若是須要把某個集合包裝成線程安全的集合,則應該在建立以後當即包裝

        HashMap m=Collections.synchronizedMap(new HashMap());

    • 線程安全的集合類

      • java.util.concurrent

      • 支持高效併發訪問的集合接口和實現類

        1. Concurrent開頭的集合類:支持併發訪問的集合

        2. CopyOnWrite開頭的集合類:適合讀取操做遠遠大於寫入操做的場景,如緩存等

相關文章
相關標籤/搜索