重入读写锁ReentrantReadWriteLock特性总结
- 重入性:因为是可重入锁,而且是同一个线程内,故可以重复获取到锁,普通Lock即时是同一线程也无法重复获取,是不可重入的;重入多少次就得释放多少次。
- 互斥性与锁升降级:读读不互斥,读写&写写互斥;;;同一个线程内不适应该规则,但同一线程内如本例属于锁降级情况是OK的,但是如果是先读锁再加写锁则是锁升级,会发生死锁
- 公平性:ReentrantReadWriteLock声明为true公平锁,即“线程等待锁排序”与“线程最终获取锁排序”是一致的,否则抢占
- 分布式环境下解决方案 redission分布式环境readWriteLock
public class App {
private static final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
public static void main(String[] args) throws Exception {
Thread t = new Thread(() -> {
readWriteLock.writeLock().lock();
System.out.println("writeLock1");
readWriteLock.writeLock().lock();//因为是可重入锁,而且是同一个线程内,故可以重复获取到锁,普通Lock即时是同一线程也无法重复获取;
System.out.println("writeLock1");
readWriteLock.readLock().lock(); //不同线程:读读不互斥,读写&写写互斥;;;同一个线程内不适应该规则,但同一线程内如本例属于锁降级情况是OK的,但是如果是先读锁再加写锁则是锁升级,会发生死锁
System.out.println("readLock1");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
readWriteLock.writeLock().unlock();
readWriteLock.writeLock().unlock();//前面锁了两次,故需要释放两次
readWriteLock.readLock().unlock();
});
t.start();
Thread.sleep(1000);
//启动N个线程:测试公平锁、非公平锁
for (int i = 0; i < 100; i++) {
int finalI = i;
new Thread(() -> {
System.out.println("线程等待锁排序"+finalI);
//由于写锁已被t线程获取,t线程获取的写锁排序这里的读锁,故在此处阻塞。5s后t线程释放锁,由于该ReentrantReadWriteLock声明为true公平锁,即“线程等待锁排序”与“线程最终获取锁排序”是一致的
readWriteLock.readLock().lock();
System.out.println("线程最终获取锁排序"+ finalI);
}).start();
}
}
}