java concurrent 並發包學習記錄


未完待續

 

參考:

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 
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
Condition

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM