理解J.U.C中的ReentrantLock

2020-06-01  本文已影响0人  吉他手_c156

JUC(java.util.concurrent工具包的简称)

Lock(synchronized)

ReentrantLock 重入锁
// 重入锁
    private static Lock lock = new ReentrantLock();
    private static int count = 0;
    public static void inc(){
        lock.lock();  // 获得锁
        try {
            Thread.sleep(1);
            count++;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();  // 锁
        }
    }

Lock 它不会像 synchronized 自动释放锁,而是要手动释放锁,否则别的线程是无法抢占到锁的,所以需要在 finally 中去做一个释放锁的操作

ReentrantReadWriteLock 重入读写锁

读和读不互斥,读和写互斥,写和写互斥,在读多写少的情况下,读数据是不需要互斥的,因为读本身不会影响数据的改变,引入读写锁是为了解决原本互斥锁带来的性能问题。

public class ReentrantReadWriteLockDemo {

    static Map<String,Object> cacheMap = new HashMap<String, Object>();
    static ReadWriteLock rwl = new ReentrantReadWriteLock();
    static Lock read = rwl.readLock(); // 读锁
    static Lock write = rwl.writeLock(); // 写锁

    public static Object get(String key){
        read.lock(); // 读锁
        try {
            // TODO  业务......
        }finally {
            read.unlock(); // 释放锁
        }
        return cacheMap.get(key);
    }

    public static void set(String key ,Object value){
        write.lock();  // 写锁
        try{
            //  TODO   业务.....
        }finally {
            write.unlock(); // 释放锁
        }
    }
}
重入锁的特性

看代码

    // 重入锁
    private static Lock lock = new ReentrantLock();
    private static int count = 0;
    public static void inc(){
        lock.lock();  // 获得锁
        try {
            Thread.sleep(1);
            count++;

            decr();   // 调用减减操作
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();  // 锁
        }
    }
    
    public static void decr(){
        lock.lock();  // 获得锁
        try{
            count --;
        }finally {
            lock.unlock();  // 释放锁
        }
    }

正如上面代码操作,假设线程 A 进入 inc() 方法抢占到了锁,这是方法走到 decr() 方法中,又去抢占锁,而这时需要 inc() 方法释放锁,decr() 方法才能继续抢占锁,但是这里线程 A 在 inc() 方法中无法释放掉锁,这样你等你我等你,就会出现死锁情况!而重入锁的重入特性就避免了这一情况,在 decr() 方法中不需要在此抢占锁,而只是增加重入的次数。


image.png

思考锁的实现(设计思维)

互斥,就是说多个线程访问某个共享资源的时候,只有一个线程可以持有资源,其他线程无法持有

技术方案


上一篇下一篇

猜你喜欢

热点阅读