Lock
- Lock.lock 进入锁
- Lock.unLock 释放锁
- Lock.tryLock 获取锁 (return boolean)
ReentrantLock 可重入锁
- 创建ReentrantLock 默认情况下是非公平锁
- new ReentrantLock(true) 这样是公平锁
- synchronized 也是非公平锁
- synchronized 和 ReentrantLock 都是排它锁,也就是同一时间只能拥有一个锁
private Lock lock = new ReentrantLock();
private int count = 1;
/**
* 必须要try finally
* 因为try 的流程出现异常,会导致锁无法释放
* 无法释放锁,可能会导致哪一块空间无法释放,其他线程无法获取锁
*/
public void test() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
ReentrantReadWriteLock 可重入的读写锁
- 之前说 synchronized 和 ReentrantLock 都是排它锁;而ReentrantReadWriteLock是一种包含排它锁和共享锁的锁。
- 在保证数据一致性的情况下,在进入读锁的情况下,不允许写入,也就是无法进入写锁;反之,在写锁的情况下,也无法进入读取操作,也就是无法进入读锁。
- 读的时候,可以有多个读线程进入,这是不允许写;写的时候,只有这个写的线程可以进行,任何其他的写线程或者读线程都不被允许。
- 这个锁存在是因为读的操作大于写的操作,也就是一个程序中,读数据的功能会大于写功能;所以基本状况也就是读锁多于写锁。
- 相对于synchronized 和 ReentrantLock,ReentrantReadWriteLock的效率更高。
private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
private Lock readLock = reentrantReadWriteLock.readLock();
private Lock writeLock = reentrantReadWriteLock.writeLock();
private int count = 1;
public int readData() {
readLock.lock();
try {
return count;
} finally {
readLock.unlock();
}
}
public void writeData() {
writeLock.lock();
try {
count += 1;
} finally {
writeLock.unlock();
}
}