##1.volatile關鍵字-內存可見性 內存可見性問題是,當多個線程操做共享數據時,彼此不可見。<br/> volatile關鍵字:當多個線程操做共享數據時,能夠保存內存中的數據是可見的。相較於synchronized是一種較爲輕量級的同步策略。<br> 注意:<br>html
##2.原子變量-CAS算法 ###i++的原子性問題: i++的操做實際上分爲三個步驟"讀-改-寫"。 1 int i = 10; 2 i = i++;//10java
1 int temp = i; 2 i = i + 1; 3 i = temp;
###原子變量:jdk1.5後java.util.concurrent.atomic包下提供了經常使用的原子變量: 1.volatile保證內存可見性<br/> 2.CAS(Compare-And - Swap)算法保證數據的原子性<br/> CAS 算法是硬件對於併發操做共享數據的支持<br/> CAS 包含了三個操做數:<br/> 內存值V<br/> 預估值A<br/> 更新值B<br/> 當且僅當 V == A時,V = B,不然,將不作任何操做。算法
##3.ConcurrentHashMap鎖分段機制 java5.0 在java.util.concurrent包中提供了多種併發容器類來改進同步容器的性能。<br> ConcurrentHashMap 同步容器類是java5增長的一個線程安全的哈希表。內部採用「鎖分段」機制替代Hashtable的獨佔鎖,進而提升性能。<br/> 此包還提供了設計用於多線程上下文中的Collection實現: ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet、CopyOnWriteArrayList、CopyOnWriteArraySet。當指望許多線程訪問一個給定collection時,ConcurrentHashMap 一般優於同步的HashMap,ConcurrentSkipListMap一般優於同步的TreeMap。當指望的讀數和遍歷遠遠大於列表的更新數時,CopyOnWriteArrayList優於同步的ArrayList。緩存
##4.CountDownLatch閉鎖 閉鎖:一個同步輔助類,在完成某些運算時,只有其餘全部線程的運算所有完成,當前運算才繼續執行安全
##5.實現Callable接口 **java5.0以後提供了一個新的建立執行線程的方式:Callable接口。 Callable須要依賴FutureTask,FutureTask也能夠用做閉鎖。 Callable與Runnable的異同點<br>多線程
##6.Lock同步鎖 用於解決多線程安全問題的方式:<br> synchronized:<br>併發
##9.線程按序交替 編寫一個程序,開啓 3 個線程,這三個線程的 ID 分別爲 A、B、C,每一個線程將本身的 ID 在屏幕上打印 10 遍,要求輸出的結果必須按順序顯示框架
public class TestABCAlternate { public static void main(String[] args) { AlternateDemo ad = new AlternateDemo(); new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= 20; i++) { ad.loopA(i); } } }, "A").start(); new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= 20; i++) { ad.loopB(i); } } }, "B").start(); new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= 20; i++) { ad.loopC(i); System.out.println("-----------------------------------"); } } }, "C").start(); } } class AlternateDemo{ private int number = 1; //當前正在執行線程的標記 private Lock lock = new ReentrantLock(); private Condition condition1 = lock.newCondition(); private Condition condition2 = lock.newCondition(); private Condition condition3 = lock.newCondition(); /** * @param totalLoop : 循環第幾輪 */ public void loopA(int totalLoop){ lock.lock(); try { //1. 判斷 if(number != 1){ condition1.await(); } //2. 打印 for (int i = 1; i <= 1; i++) { System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop); } //3. 喚醒 number = 2; condition2.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void loopB(int totalLoop){ lock.lock(); try { //1. 判斷 if(number != 2){ condition2.await(); } //2. 打印 for (int i = 1; i <= 1; i++) { System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop); } //3. 喚醒 number = 3; condition3.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void loopC(int totalLoop){ lock.lock(); try { //1. 判斷 if(number != 3){ condition3.await(); } //2. 打印 for (int i = 1; i <= 1; i++) { System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop); } //3. 喚醒 number = 1; condition1.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }
##10.ReadWirteLock讀寫鎖 ReadWriteLock維護了一對相關的鎖,一個用於只讀操做,另外一個用於寫入操做。只要沒有Writer,讀取鎖能夠由多個reader線程同時保持。寫入鎖是獨佔的。<br> ReadWriteLock 讀取操做一般不會改變共享資源,但執行寫入操做時,必須獨佔方式來獲取鎖。ide
##11.線程池 第四種獲取線程的方法: 線程池,一個ExecutorService,它使用可能的幾個線程池之一執行每一個提交的任務,一般使用Executors工廠方法配置。<br/> 1、線程池:提供了一個線程隊列,隊列中保存着全部等待狀態的線程。避免了建立與銷燬額外開銷,提升了響應的速度。<br> 2、線程池的體系結構:<br> java.util.concurrent.Executor : 負責線程的使用與調度的根接口<br> |--ExecutorService 子接口: 線程池的主要接口<br> |--ThreadPoolExecutor 線程池的實現類<br> |--ScheduledExecutorService 子接口:負責線程的調度<br> |--ScheduledThreadPoolExecutor :繼承 ThreadPoolExecutor, 實現 ScheduledExecutorService<br> 3、工具類 : Executors <br> ExecutorService newFixedThreadPool() : 建立固定大小的線程池<br> ExecutorService newCachedThreadPool() : 緩存線程池,線程池的數量不固定,能夠根據需求自動的更改數<br> ExecutorService newSingleThreadExecutor() : 建立單個線程池。線程池中只有一個線程<br> ScheduledExecutorService newScheduledThreadPool() : 建立固定大小的線程,能夠延遲或定時的執行任務。 ##12.線程調度 一個ScheduledExecutorService,可安排在給定的延遲後運行或按期地執行命令。 ##13.ForkJoinPool 分支/合併框架 工做竊取 Fork/Join框架:就是在必要的狀況下,將一個大任務,進行拆分紅若干個小任務(拆到不可再拆時),再將一個個的小人物運算的結果進行join彙總。<br>工具
工做竊取 : 當執行新的任務時它能夠將其拆分分紅更小的任務執行,並將小任務加到線程隊列中,而後再從一個隨機線程的隊列中偷一個並把它放在本身的隊列中,而後再從一個隨機線程的隊列中偷一個並把它放在本身的隊列中。
原文出處:https://www.cnblogs.com/liben123/p/11082263.html