ReadWriteLock

HeJin大约 1 分钟JavaJUC并发编程

image-20210312105427511
image-20210312105427511

读可以被多线程同时读,写的时候只能由一个线程写。

public class ReadWriteLockDemo {
    public static void main(String[] args) {
        MyCacheLock myCache = new MyCacheLock();

        for (int i = 1; i <= 5; i++) {
            final int temp = i;
            new Thread(() -> {
                myCache.put(temp+"", temp+"");
            },String.valueOf(i)).start();
        }
        for (int i = 1; i <= 5; i++) {
            final int temp = i;
            new Thread(() -> {
                myCache.get(temp+"");
            },String.valueOf(i)).start();
        }

    }
}

/**
 * 自定义缓存
 */
class MyCacheLock{
    private volatile Map<String, Object> map = new HashMap<>();
    /** 读写锁:更加细粒度的控制 **/
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    /**
     * 存,写:只希望同时只有一个线程写
     */
    public void put(String key, String value){
        readWriteLock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"写入"+key);
            map.put(key, value);
            System.out.println(Thread.currentThread().getName()+"写入OK");
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }

    /**
     * 取,读:所有人都可以读
     */
    public void get(String key){
        readWriteLock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"读取"+key);
            Object o = map.get(key);
            System.out.println(Thread.currentThread().getName()+"读取OK");
        } finally {
            readWriteLock.readLock().unlock();
        }
    }
}

结果:

2写入2
2写入OK
1写入1
1写入OK
3写入3
3写入OK
4写入4
4写入OK
5写入5
5写入OK
3读取3
2读取2
3读取OK
1读取1
1读取OK
4读取4
4读取OK
2读取OK
5读取5
5读取OK

Process finished with exit code 0

读锁和写锁是互斥的,也就是说,写的时候也不能读。但是你不加读锁,那就会写的时候能够异步读。更简单点理解就是:加写锁读写都不可以。加读锁可以读不可以写。

独占锁

写锁。一次只能被一个线程占用。

共享锁

读锁。多个线程可以同时占用。