Lock Objects 锁对象

同步代码依赖一种简单的可重入锁。虽然这种锁很容易使用,但是有许多局限。许多复杂的锁形式是由java.util.concurrent.locks包支持。我们不详细解释这个包,但是了关注它最重要最基本的接口,Lock。

Lock对象的工作机制与用同步代码的隐式锁很相似。作为隐式锁,只有一个线程能一次拥有一个锁对象。所对象也支持wait/notify机制。,通过它们关联的条件对象。

锁对象超过瘾式锁的最大优点是它们能撤回试图获取一个锁。tryLock方法会立即撤回如果发现锁是不可用的或者时间超时(如果有时间限制)。lockInterruptibly 方法撤回,如果另外一个线程发了一个中断在获取到锁之前。

让我们使用锁对象解决活性(Liveness)小节中的死锁问题。Alphonse和Gaston已经训练他们去通知,当一个朋友将鞠躬的时候。我们改进了模型,通过要求在互相鞠躬前我们的朋友对象必须获取参与者双方的锁。这里是改进模型的源码,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();
}
}

这里后面添加这段源码的分析。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值