Java 理论与实践: 平衡测试,第 3 部分:用方面检验设计约束
2010-01-11 00:00:00 来源:WEB开发网
清单 4. 把所有 ReentrantLock 的实例化替换成 DebuggingLock 的方面public aspect ReentrantLockAspect {
pointcut newLock() : call(ReentrantLock.new());
pointcut newLockFair(boolean fair) :
call(ReentrantLock.new(boolean)) && args(fair);
ReentrantLock around() : newLock() {
return new DebuggingLock();
}
ReentrantLock around(boolean fair) : newLockFair(fair) {
return new DebuggingLock (fair);
}
}
在 Java SE 6 中,运行时对请求执行死锁检测,通过 java.lang.management 中的 ThreadMXBean 接口,或者在请求线程转储时执行。清单 5 显示了 DebuggingLock 的一个可能实现,每次请求锁时,都执行死锁检测,所以可以更迅速地得到死锁的警告。锁定性能要比 ReentrantLock 差,因为每次试图锁定时要做更多的工作,所以这种方式可能不适合在生产中使用。(而且,维护 waitingFor 数据结构时自带的同步,可能会干扰应用程序的计时,从而改变死锁的可能性。)
清单 5. ReentrantLock 的调试版本会在检测到死锁时抛出 AssertionErrorpublic class DebuggingLock extends ReentrantLock {
private static ConcurrentMap<Thread, DebuggingLock> waitingFor
= new ConcurrentHashMap<Thread, DebuggingLock>();
public DebuggingLock() { super(); }
public DebuggingLock(boolean fair) { super(fair); }
private void checkDeadlock() {
Thread currentThread = Thread.currentThread();
Thread t = currentThread;
while (true) {
DebuggingLock lock = waitingFor.get(t);
if (lock == null || !lock.isLocked())
return;
else {
t = lock.getOwner();
if (t == currentThread)
throw new AssertionError("Deadlock detected");
}
}
}
public void lock() {
if (tryLock())
return;
else {
waitingFor.put(Thread.currentThread(), this);
try {
checkDeadlock();
super.lock();
}
finally {
waitingFor.remove(Thread.currentThread());
}
}
}
}
更多精彩
赞助商链接