java读写锁ReentrantReadWriteLock使用
为什么要使用读写锁
读写锁采用读锁与写锁分离等待方法,能够更加细粒度进行代码同步。提高代码并发量。如代码都是进行读操作时,多线程读取并不会带来线程安全问题,若加入锁,则会带来没必要的资源浪费,影响代码运行速度。引入读写锁能解决此问题
读写锁遵循规则
- 当读锁被获取时,写锁无法被获取,而读锁能正常被获取
- 当写锁被获取时,读锁和写锁都无法被获取
代码实现
线程资源类
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个写线程
可以看到在获取读锁被获取后,其他线程依然能正常获取,而在读锁被持有时,无法获取写锁,只有读锁被释放后,才能获取读锁;若写锁被持有,读锁也不能被获取。
