java读写锁ReentrantReadWriteLock使用

为什么要使用读写锁

读写锁采用读锁与写锁分离等待方法,能够更加细粒度进行代码同步。提高代码并发量。如代码都是进行读操作时,多线程读取并不会带来线程安全问题,若加入锁,则会带来没必要的资源浪费,影响代码运行速度。引入读写锁能解决此问题

读写锁遵循规则

  1. 当读锁被获取时,写锁无法被获取,而读锁能正常被获取
  2. 当写锁被获取时,读锁和写锁都无法被获取

代码实现

线程资源类

class Readwrite {
    private volatile int count = 0;
    ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    public void write() {
        readWriteLock.writeLock().lock();
        System.out.println("获取写锁");
        count++;
        System.out.println("执行了写操作count = " + count);
        try {
            Thread.sleep(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("解除写锁");
        readWriteLock.writeLock().unlock();
    }

    public void read() {
        readWriteLock.readLock().lock();
        System.out.println("获取读锁");
        System.out.println("执行了读操作count = " + count);
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        readWriteLock.readLock().unlock();
        System.out.println("解除读锁");
    }

}

测试方法:

public static void main(String[] args) {
        //创建一个核心线程数为5,最大线程数为10,非核心线程闲置6秒后进行回收,排队等待阻塞队列长度为3的线程池
        ExecutorService executorService = new ThreadPoolExecutor(5, 10, 1L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());


        Readwrite readwrite = new Readwrite();
        for (int i = 0; i < 5; i++) {
            executorService.execute(() -> {
                readwrite.read();
            });
        }

        for (int i = 0; i < 5; i++) {
            executorService.execute(() -> {
                readwrite.write();
            });
        }

    }

创建了5个读线程,5个写线程
java读写锁ReentrantReadWriteLock使用_第1张图片

可以看到在获取读锁被获取后,其他线程依然能正常获取,而在读锁被持有时,无法获取写锁,只有读锁被释放后,才能获取读锁;若写锁被持有,读锁也不能被获取。

你可能感兴趣的:(多线程,java,并发编程)