除了 synchronized,Java 中还有别的方式来保证数据资源安全
public class ReadWriteLockTest {
private int x = 0;
ReentrantLock reentrantLock = new ReentrantLock();
private void count() {
reentrantLock.lock();
x++;
reentrantLock.unlock();
}
}
在 count 方法中 通过 lock 和 unlock 来执行加锁和解锁来保证数据安全
但是我们不能保证在 lock 和 unlock 之间的代码不会抛出异常,如果抛出异常,则 unlock 永远得不到执行,就会永远处于锁住的状态
所以说
public class ReadWriteLockTest {
private int x = 0;
ReentrantLock reentrantLock = new ReentrantLock();
private void count() {
reentrantLock.lock();
try {
x++;
} finally {
reentrantLock.unlock();
}
}
}
到此,我们同步一个概念,每个线程对数据都有两个操作:读、写,两个线程就有四种情况,两个线程随机进行操作的时候,哪些组合是被允许同时存在,哪些是不行的呢?
线程1 | 线程2 | 结果 |
---|---|---|
读 | 读 | 可以 |
读 | 写 | 不行 |
写 | 读 | 不行 |
写 | 写 | 不行 |
对于 synchronized 来说,在同时都读的时候,他就没必要加锁,加了锁性能就降低了
更改代码
public class ReadWriteLockTest {
private int x = 0;
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
Lock readLock = lock.readLock();
Lock writeLock = lock.writeLock();
private void count() {
writeLock.lock();
try {
x++;
} finally {
writeLock.unlock();
}
}
private void get() {
readLock.lock();
try {
System.out.println(x + "");
} finally {
readLock.unlock();
}
}
}