共计 1968 个字符,预计需要花费 5 分钟才能阅读完成。
Lock 对象
同步代码依赖于简单的可重入锁,这种锁易于使用,但有许多限制,java.util.concurrent.locks 包支持更复杂的锁定语法,我们不会详细检查这个包,而是将重点放在其最基本的接口 Lock 上。
Lock 对象的工作方式与同步代码使用的隐式锁定非常相似,与隐式锁一样,一次只有一个线程可以拥有一个 Lock 对象,Lock 对象还通过其关联的 Condition 对象支持 wait/notify 机制。
Lock 对象优于隐式锁的最大优点是它们能够退出获取锁的尝试,如果锁立即不可用或超时到期之前(如果指定),则 tryLock 方法退出,如果另一个线程在锁被获得之前发送中断,则 lockInterruptibly 方法将退出。
让我们使用 Lock 对象来解决我们在活性中看到的死锁问题,Alphonse 和 Gaston 训练自己注意朋友什么时候要鞠躬。我们通过要求我们的 Friend 对象必须在继续执行 bow 之前获取两个参与者的锁来对此进行建模,以下是改进模型 Safelock 的源代码。为了演示这个语法的多功能性,我们假设 Alphonse 和 Gaston 如此迷恋他们新发现的安全鞠躬能力,他们不能停止相互鞠躬:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Random;
public class Safelock {
static class Friend {
private final String name;
private final Lock lock = new ReentrantLock();
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public boolean impendingBow(Friend bower) {
Boolean myLock = false;
Boolean yourLock = false;
try {
myLock = lock.tryLock();
yourLock = bower.lock.tryLock();
} finally {
if (! (myLock && yourLock)) {
if (myLock) {
lock.unlock();
}
if (yourLock) {
bower.lock.unlock();
}
}
}
return myLock && yourLock;
}
public void bow(Friend bower) {
if (impendingBow(bower)) {
try {
System.out.format(“%s: %s has”
+ ” bowed to me!%n”,
this.name, bower.getName());
bower.bowBack(this);
} finally {
lock.unlock();
bower.lock.unlock();
}
} else {
System.out.format(“%s: %s started”
+ ” to bow to me, but saw that”
+ ” I was already bowing to”
+ ” him.%n”,
this.name, bower.getName());
}
}
public void bowBack(Friend bower) {
System.out.format(“%s: %s has” +
” bowed back to me!%n”,
this.name, bower.getName());
}
}
static class BowLoop implements Runnable {
private Friend bower;
private Friend bowee;
public BowLoop(Friend bower, Friend bowee) {
this.bower = bower;
this.bowee = bowee;
}
public void run() {
Random random = new Random();
for (;;) {
try {
Thread.sleep(random.nextInt(10));
} catch (InterruptedException e) {}
bowee.bow(bower);
}
}
}
public static void main(String[] args) {
final Friend alphonse =
new Friend(“Alphonse”);
final Friend gaston =
new Friend(“Gaston”);
new Thread(new BowLoop(alphonse, gaston)).start();
new Thread(new BowLoop(gaston, alphonse)).start();
}
}
上一篇:高级并发对象