- 如果有一个线程已经占用了读锁,则此时其他线程如果要申请读锁,可以申请成功。
- 如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁,因为读写不能同时操作。
- 如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,都必须等待之前的线程释放写锁,同样也因为读写不能同时,并且两个线程不应该同时写。
读读共享、其他都互斥(写写互斥、读写互斥、写读互斥)
一个简单的例子
public class TestReadWriteLock {
public static void main(String[] args) {
ReadWriteLockDemo test = new ReadWriteLockDemo();
ExecutorService pool = Executors.newFixedThreadPool(20);
// 开启10个线程写入数据 (模拟改变数据)
for (int i = 0; i < 10; i++) {
pool.execute(() -> {
test.set(new Random().nextInt(10));
});
}
// 读取这个数据
pool.execute(test::read);
pool.shutdown();
}
}
class ReadWriteLockDemo {
private static int num = 0;
private static ReadWriteLock lock = new ReentrantReadWriteLock();
private static Lock writeLock = lock.writeLock();
private static Lock readLock = lock.readLock();
void read() {
readLock.lock();
try {
System.out.println("当前num的值为" + num);
} finally {
readLock.unlock();
}
}
void set(Integer num) {
writeLock.lock();
try {
System.out.println(Thread.currentThread().getName() + "===>" + num);
Thread.sleep(1000);
ReadWriteLockDemo.num = num;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
writeLock.unlock();
}
}
}