读写锁ReadWriteLock
About 1 min
使用
public class ReadWriteLockMain {
private static int value = 0;
static void read(Lock lock) {
try {
lock.lock();
TimeUnit.SECONDS.sleep(1);
System.out.printf("Finish read %d, time: %s\n", value, LocalDateTime.now());
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
static void write(Lock lock, int newVal) {
try {
lock.lock();
TimeUnit.SECONDS.sleep(1);
value = newVal;
System.out.printf("Finish write %d, time: %s\n", newVal, LocalDateTime.now());
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
var lock = new ReentrantReadWriteLock();
for (int i = 0; i < 3; i++) new Thread(() -> read(lock.readLock())).start();
for (int i = 0; i < 2; i++) new Thread(() -> write(lock.writeLock(), new Random().nextInt(12))).start();
}
}
输出结果是:
Finish read 0, time: 2023-09-07T10:42:19.531316
Finish read 0, time: 2023-09-07T10:42:19.531389
Finish read 0, time: 2023-09-07T10:42:19.531318
Finish write 8, time: 2023-09-07T10:42:20.549605
Finish write 9, time: 2023-09-07T10:42:21.553636
如果修改上述的main
方法如下:
public static void main(String[] args) {
var lock = new ReentrantLock();
for (int i = 0; i < 3; i++) new Thread(() -> read(lock)).start();
for (int i = 0; i < 2; i++) new Thread(() -> write(lock, new Random().nextInt(12))).start();
}
那么此次的输出结果:
Finish read 0, time: 2023-09-07T10:43:06.426840
Finish read 0, time: 2023-09-07T10:43:07.442590
Finish read 0, time: 2023-09-07T10:43:08.448698
Finish write 6, time: 2023-09-07T10:43:09.453418
Finish write 7, time: 2023-09-07T10:43:10.457287
分析
FAQ
总结
ReadWriteLock
可以提高读取效率,适合于读多写少的场景
ReadWriteLock
只允许一个线程写入,在写入时线程不能读取(线程安全)ReadWriteLock
在没有写入的时候,多个线程是可以同时读取(提高性能)