java 普通容器,同步容器,併發容器,同步工具

同步容器,如HashTable,提供獨佔訪問。html

 

併發容器,ConcurrentHashMap,有着更好的併發性能,可是不能獨佔訪問。java

 --putIfAbsentspring

 

同步工具:安全

閉鎖:CountDownLatch多線程

FutureTask併發

Semaphoreapp

柵欄:Barrier框架

 

Executor框架:jvm

Executors.newFixedThreadPool()函數

Executors.newCachedThreadPool()

ExecutorService接口,獲取Future運行結果。

CompletionService接口,ExecutorCompletionService,並行運行,並等待結果。

...等

 

java並無提供某種搶佔式的機制來取消操做或者終結內存,它提供了一種協做式的中斷機制來實現取消操做。

當有界隊列被填滿後,飽和策略開始發揮做用。

--終止策略,拋棄任務,並拋出未受檢異常

--調用者運行策略。

--對策略進行修改。

 

線程工廠ThreadFactory。自定義線程工廠,爲新線程指定UncaughtExceptionHandler、定製Thread類用於記錄信息等。

 

定製和擴展ThreadPoolExcutor。

--定製:自定義線程池大小、存活時間、線程工廠、飽和策略等。

--擴展:beforeExecute(),afterExecute和terminate()。能夠添加計時、日誌、統計和信息收集功能。

 

stream並行處理,CompletableFuture

 

關閉和取消:

1. 如何好的關閉一個任務?

任務和線程是獨立的,也就是說線程運行任務,可是關閉任務並不意味着退出線程。

a)stop()函數----@Deprecated。已經棄用,由於強制退出線程,會形成不少沒法預料的錯誤。

     * @deprecated This method is inherently unsafe.  Stopping a thread with
     *       Thread.stop causes it to unlock all of the monitors that it
     *       has locked (as a natural consequence of the unchecked
     *       <code>ThreadDeath</code> exception propagating up the stack).  If
     *       any of the objects previously protected by these monitors were in
     *       an inconsistent state, the damaged objects become visible to
     *       other threads, potentially resulting in arbitrary behavior.  Many
     *       uses of <code>stop</code> should be replaced by code that simply
     *       modifies some variable to indicate that the target thread should
     *       stop running.  The target thread should check this variable
     *       regularly, and return from its run method in an orderly fashion
     *       if the variable indicates that it is to stop running.  If the
     *       target thread waits for long periods (on a condition variable,
     *       for example), the <code>interrupt</code> method should be used to
     *       interrupt the wait.

b)使用共享變量。

在遇到阻塞等待時,就失去效果了。

https://stackoverflow.com/questions/10961714/how-to-properly-stop-the-thread-in-java

c)使用中斷。

須要任務代碼的支持,只能解決拋出InterruptedException異常的阻塞,若是任務代碼不支持或者如IO阻塞等,也失去了效果。

d)處理不可中斷的阻塞。

本身實現Thread的繼承類,重寫interrupt()函數,自行關閉阻塞的函數,如關閉IO鏈接等。

http://www.cnblogs.com/simbachen/p/4009562.html

總結:若是寫多線程程序時,須要考慮提早結束的狀況,那麼要有任務代碼的支持。任務代碼必需要考慮如何響應中斷,如何提早關閉,而不是隻考慮計算邏輯等待線程被強制結束。

由於強制結束會有不少不肯定因素,好比可能部分修改了對象中的變量,標誌位沒有恢復,IO未關閉等。

ps. 對繼承的認識有了提升,之前以爲繼承只是爲了繼承一些屬性和行爲,如今發現能夠作的事情不少,能夠擴展行爲,能夠改變行爲。

 

處理非正常的線程終止:捕獲RuntimeException。

未捕獲異常的處理:繼承UncaughtExceptionHandler,有點像spring中的ExceptionHandler;ThreadGroup。

鉤子:經過Runtime.getRuntime().addShutdownHook()註冊。當jvm關閉的時候,會執行系統中已經設置的全部經過方法addShutdownHook添加的鉤子,當系統執行完這些鉤子後,jvm纔會關閉。因此這些鉤子能夠在jvm關閉的時候進行內存清理、對象銷燬等操做。

同一個JVM最好只使用一個關閉鉤子,而不是每一個服務都使用一個不一樣的關閉鉤子,使用多個關閉鉤子可能會出現當前這個鉤子所要依賴的服務可能已經被另一個關閉鉤子關閉了。爲了不這種狀況,建議關閉操做在單個線程中串行執行,從而避免了再關閉操做之間出現競態條件或者死鎖等問題。

http://www.cnblogs.com/zhuawang/p/4523503.html

守護線程,非守護線程:

 

 

考慮多線程的代價。

1. 死鎖

2. 性能。上下文切換,內存同步,阻塞。

3. 鎖的競爭。鎖分段,鎖分解。

測試多線程。

1. 貼近真實場景

2. 線程執行的不肯定性。

3. 使用 回調函數 或者 擴展類 獲取信息。

4. 考慮垃圾回收、動態編譯/編譯優化的影響。

 

ReentrantLock、ReadWriteLock和synchronized內置鎖

1. ReentrantLock實現Lock接口,更豐富,提供定時的鎖等待、可中斷的鎖等待、公平性選擇。可是是互斥的。

 2. synchronized編寫簡單,出代碼塊時自動unlock。

3. 讀寫鎖ReadWriteLock。可選讀優先/寫優先,多個讀一個寫。

 

java更底層的同步機制

synchronized和wait/notify/notifyAll結合使用,注意「過早喚醒」和「信號丟失」狀況。

Condition,更細分等待線程。

 

悲觀鎖--獨佔性,lock

樂觀鎖--CAS(會有ABA問題)

 

安全的發佈/不安全的發佈:缺乏happens-before關係時,會出現重排序現象

相關文章
相關標籤/搜索