java并發(fā)編程的藝術(shù)筆記第五章——java中的鎖

1、Lock接口

鎖是用來控制多個(gè)線程訪問共享資源的方式,一般來說鎖能夠防止多個(gè)線程同時(shí)訪問共享資源(有的鎖可以允許多個(gè)線程訪問共享資源,比如說讀寫鎖),在Lock接口出現(xiàn)之前,java程序是靠synchronized關(guān)鍵字實(shí)現(xiàn)鎖功能的,但是在JKD1.5之后并發(fā)包中新增了Lock接口及其實(shí)現(xiàn)來實(shí)現(xiàn)鎖的功能。它提供了synchronized關(guān)鍵字類似的功能,但是Lock需要顯示的獲取鎖、釋放鎖,而synchronized是通過隱式的方式來實(shí)現(xiàn)獲取、釋放鎖。

Lock接口常見的API請自行查找

2、隊(duì)列同步器

略...

3、重入鎖

重入鎖ReentrantLock,顧名思義,就是支持重進(jìn)入的鎖,重入鎖支持同一個(gè)線程多次的獲取鎖。除此之外,該鎖還支持獲取鎖時(shí)的公平和非公平性。

關(guān)于鎖的公平性,如果在絕對的時(shí)間上,先對鎖進(jìn)行獲取請求的操作一定會(huì)先被滿足,則說明這個(gè)鎖是公平的,反之則是不公平的。ReentrantLock的構(gòu)造函數(shù)支持構(gòu)造公平鎖與非公平鎖,默認(rèn)為非公平鎖,因?yàn)榉枪芥i能減少上下文切換,開銷更小。

4、讀寫鎖

讀寫鎖支持同一時(shí)刻允許多個(gè)線程同時(shí)訪問,但是在寫線程訪問時(shí),所有的讀線程與其他的寫線程均被阻塞。讀寫鎖維護(hù)了一對鎖,讀鎖與寫鎖,通過讀鎖與寫鎖的分離,讀寫鎖的并發(fā)性相比于其他排他鎖都有很大的提升。

java并發(fā)包提供的讀寫鎖是ReentrantReadWriteLock,它具有公平性選擇、鎖重入、鎖降級三個(gè)特性。

讀寫鎖實(shí)現(xiàn)簡單緩存demo

package main.java.com.robot.demo;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author: 會(huì)跳舞的機(jī)器人
 * @date: 2017/8/16 14:45
 * @description: 讀寫鎖實(shí)現(xiàn)緩存demo
 */
public class Cache {
    static Map<String, Object> map = new HashMap<>();
    static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    static Lock writeLock = rwl.writeLock();
    static Lock readLock = rwl.readLock();

    /**
     * 讀緩存
     */
    public static final Object get(String key) {
        readLock.lock();
        try {
            return map.get(key);
        } finally {
            readLock.unlock();
        }
    }

    /**
     * 寫入緩存
     */
    public static final Object put(String key, Object value) {
        writeLock.lock();
        try {
            return map.put(key, value);
        } finally {
            writeLock.unlock();
        }
    }

    /**
     * 清空緩存
     */
    public static final void clear() {
        writeLock.lock();
        try {
            map.clear();
        } finally {
            writeLock.unlock();
        }
    }

    /**
     * 獲取緩存大小
     */
    public static final int size() {
        writeLock.lock();
        try {
            return map.size();
        } finally {
            writeLock.unlock();
        }
    }
}

5、LockSupport工具

略...

6、Condition接口

利用Condition接口來實(shí)現(xiàn)一個(gè)簡單的有界阻塞隊(duì)列,當(dāng)隊(duì)列為空時(shí),隊(duì)列的獲取操作將會(huì)阻塞獲取線程,知道有新的元素添加進(jìn)來,當(dāng)隊(duì)列滿時(shí),隊(duì)列的插入操作將會(huì)阻塞插入線程,知道隊(duì)列出現(xiàn)“空位”。

package main.java.com.robot.demo;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author: 會(huì)跳舞的機(jī)器人
 * @date: 2017/8/16 15:48
 * @description: Condition實(shí)現(xiàn)有界阻塞隊(duì)列demo
 */
public class BoundedQueue {
    private Object[] items;

    private int addIndex, removeIndex, count;

    private Lock lock = new ReentrantLock();

    private Condition notEmpty = lock.newCondition();

    private Condition notFull = lock.newCondition();

    public BoundedQueue(int size) {
        items = new Object[size];
    }

    /**
     * 添加一個(gè)元素,如果隊(duì)列已滿,則線程進(jìn)入等待狀態(tài),直到有空位為止
     */
    public void add(Object object) throws InterruptedException {
        lock.lock();
        try {
            // 隊(duì)列已滿,阻塞線程
            while (items.length == count) {
                System.out.println("隊(duì)列已滿,等待......");
                notFull.await();
            }
            items[addIndex] = object;
            if (++addIndex == items.length) {
                addIndex = 0;
            }
            ++count;
            // 喚醒
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 刪除隊(duì)列的第一個(gè)元素,如果隊(duì)列為空,則線程進(jìn)入等待狀態(tài),直到有新元素添加進(jìn)來
     */
    public Object remove() throws InterruptedException {
        lock.lock();
        try {
            while (count == 0) {
                System.out.println("空隊(duì)列,等待......");
                notEmpty.await();
            }
            Object obj = items[removeIndex];
            if (++removeIndex == items.length) {
                removeIndex = 0;
            }
            --count;
            notFull.signal();
            return obj;
        } finally {
            lock.unlock();
        }
    }

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容