未完待續
參考:
https://blog.csdn.net/wbwjx/article/details/57856045
https://blog.csdn.net/defonds/article/details/44021605#t19
http://www.blogjava.net/xylz/archive/2010/07/08/325587.html
請先參考上面的鏈接,本文只是作為記錄我學習博客的過程
java.util.concurrent 包是專為 Java並發編程而設計的包。包下的所有類可以分為如下幾大類:
locks部分:顯式鎖(互斥鎖和速寫鎖)相關;
atomic部分:原子變量類相關,是構建非阻塞算法的基礎;
executor部分:線程池相關;
collections部分:並發容器相關;
tools部分:同步工具相關,如信號量、閉鎖、柵欄等功能;
腦圖地址: http://www.xmind.net/m/tJy5,
Lock部分
類似於synchronized 的線程同步機制
自旋鎖:如果獲取鎖未獲取到,會一直循環查看是否鎖被釋放
互斥鎖:如果獲取鎖未獲取到,會進入睡眠狀態等待
共享鎖:只是一個標志,所有線程都等待這個標志是否滿足,一旦滿足,所有線程都被激活
ReentrantLock 可重入鎖
可中斷響應、鎖申請等待限時、公平鎖等機制,以及結合Condition使用
1.可中斷響應:
當兩個線程1,2分別持有鎖A和鎖B並等待鎖B和鎖A,這樣就發生了死鎖,但是ReentrantLock可中斷線程,中斷線程2后,線程2釋放鎖B並不在等待鎖A,此時線程1獲取鎖執行任務,但是線程2也並沒有完成工作

public class LockTest1 { static class KillDeadlock implements Runnable{ public static ReentrantLock lock1 = new ReentrantLock(); public static ReentrantLock lock2 = new ReentrantLock(); int lock; public KillDeadlock(int lock){ this.lock = lock; } @Override public void run() { try { if (lock ==1){ lock1.lockInterruptibly(); try { Thread.sleep(5000); }catch (InterruptedException e){ } lock2.lockInterruptibly(); }else { lock2.lockInterruptibly(); try { Thread.sleep(5000); } catch (InterruptedException e) { } lock1.lockInterruptibly(); } } catch (InterruptedException e) { e.printStackTrace(); }finally { if (lock1.isHeldByCurrentThread())lock1.unlock(); if (lock2.isHeldByCurrentThread())lock2.unlock(); System.out.println(Thread.currentThread().getId()+"退出!"); } } } public static void main(String[] args) throws Exception{ KillDeadlock k1 = new KillDeadlock(1); KillDeadlock k2 = new KillDeadlock(2); Thread t1 = new Thread(k1); Thread t2 = new Thread(k2); t1.start();t2.start(); Thread.sleep(10000); t1.interrupt(); } }
2.鎖申請限時等待
可以使用tryLock()或tryLock(long timeout, TimeUtil unit) 方法進行一次限時的鎖等待。
前者如果獲取不到鎖,會立即返回false,后者等待一段時間后返回false
3.公平鎖
公平鎖會按照時間先后順序,先等待的先得到鎖,而且不會產生飢餓鎖,只要排隊等待,最終能得到獲取鎖的機會
4.Condition 配合使用
如果獲取鎖后,發現部分參數不滿足后面執行的條件,可以調用condition的await方法,繼續等待,等待其他線程修改參數后,繼續執行

public class ReentrantLockWithConditon implements Runnable{ public static ReentrantLock lock = new ReentrantLock(true); public static Condition condition = lock.newCondition(); @Override public void run() { lock.newCondition(); try { lock.lock(); System.err.println(Thread.currentThread().getName() + "-線程開始等待..."); condition.await(); System.err.println(Thread.currentThread().getName() + "-線程繼續進行了"); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public static void main(String[] args) throws InterruptedException { ReentrantLockWithConditon test = new ReentrantLockWithConditon(); Thread t = new Thread(test, "線程ABC"); t.start(); Thread.sleep(1000); System.err.println("過了1秒后..."); lock.lock(); condition.signal(); // 調用該方法前需要獲取到創建該對象的鎖否則會產生 // java.lang.IllegalMonitorStateException異常 lock.unlock(); } } --------------------- 作者:Somhu 來源:CSDN 原文:https://blog.csdn.net/Somhu/article/details/78874634 版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
ReadWriteLock 讀寫鎖
允許多個線程在同一時間對特定資源進行讀取,但同一時間內只能有一個線程對其寫入
實現類:ReentrantReadWriteLock
- 如果沒有任何寫操作鎖定,那么可以有多個讀操作鎖定該鎖
- 如果沒有任何讀操作或者寫操作,只能有一個寫線程對該鎖進行鎖定。
CountDownLatch 閉鎖
基於共享鎖實現。允許一個或者多個線程等待某個事件的發生。CountDownLatch有一個正數計數器,countDown方法對計數器做減操作,await方法等待計數器達到0。所有await的線程都會阻塞直到計數器為0或者等待線程中斷或者超時。
CyclicBarrier 循環鎖
可循環調用,它允許一組線程互相等待,直到到達某個公共屏障點 (common barrier point)。所謂屏障點就是一組任務執行完畢的時刻。
Atomic 部分
原子性包裝
將數據進行原子性封裝,變量級別的同步控制,同一時間只能有一個線程操作
Collections 部分
Queue 隊列:
BlockingQueue extends Queue 阻塞隊列
使用場景: 一個線程生產對象,另外一個線程消費對象:
有限的隊列,隊列滿時,put會阻塞,隊列空時,take會阻塞
SpecialValue : 如果操作無法執行,將返回一個特定的值,通常是true/false
注意:無法插入null
數據結構導致,除了獲取開頭和結尾之外的其他位置效率都不高
ArrayBlockingQueue 有界的阻塞隊列
ConcurrentMap 線程安全Map