一、替代synchronized进行同步
public class ReentrantLockTests {
private final Lock lock = new ReentrantLock();
private int count;
/**
* 使用lock
*/
public void add1(int n) {
lock.lock();
try {
count += n;
} finally {
lock.unlock();
}
}
/**
* 使用tryLock
* 下方代码在尝试获取锁的时候,最多等待1秒。如果1秒后仍未获取到锁,tryLock()返回false,程序就可以做一些额外处理,而不是无限等待下去。
* @param n
*/
public void add2(int n) throws InterruptedException {
if (lock.tryLock(1, TimeUnit.SECONDS)) {
try {
// 代码
} finally {
lock.unlock();
}
}
}
}
二、替代wait和notify;
public class ConditionTests {
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private Queue<String> queue = new LinkedList<>();
public void addTask(String s) {
lock.lock();
try {
queue.add(s);
condition.signalAll();
} finally {
lock.unlock();
}
}
public String getTask() throws InterruptedException {
lock.lock();
try {
while (queue.isEmpty()) {
condition.await();
}
return queue.remove();
} finally {
lock.unlock();
}
}
// 另外与tryLock类似,await可以在等待指定时间后,如果还没有被其他线程通过signal()或signalAll()唤醒,可以自己醒来:
// if (condition.await(1, TimeUnit.SECONDS)) {
// // 被其他线程唤醒
// } else {
// // 指定时间内没有被其他线程唤醒
// }
}
三、读写锁ReadWriteLock
public class ReadWriteLockTests {
private final ReadWriteLock rwlock = new ReentrantReadWriteLock();
private final Lock rLock = rwlock.readLock();
private final Lock wLock = rwlock.writeLock();
private int[] counts = new int[10];
public void inc(int index) {
wLock.lock();
try {
counts[index] += 1;
} finally {
wLock.unlock();
}
}
public int[] get() {
rLock.lock();
try {
return Arrays.copyOf(counts, counts.length);
} finally {
rLock.unlock();
}
}
}
四、StampedLock将读锁变成乐观锁
注意StampedLock是不可重入锁
public class StampedLockTests {
private final StampedLock stampedLock = new StampedLock();
private double x;
private double y;
public void move(double deltaX, double deltaY) {
long stamp = stampedLock.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
stampedLock.unlock(stamp);
}
}
public double distanceFromOrigin() {
long stamp = stampedLock.tryOptimisticRead();
double currentX = x;
double currentY = y;
if (!stampedLock.validate(stamp)) { // 检查乐观读锁后是否有其他写锁发生
stamp = stampedLock.readLock(); // 获取一个悲观读锁
try {
currentX = x;
currentY = y;
} finally {
stampedLock.unlock(stamp);
}
}
return Math.sqrt(currentX * currentX + currentY * currentY);
}
}