stop方法会终止所有未结束的方法,包括run方法。当线程被终止时,立刻释放被它锁住的所有对象的锁
这会导致对象处于不一致的状态
(转账转了一半被终止)
suspend方法不会破坏对象,但是对于持有锁的线程,调用suspend方法并不会释放锁,如果调用suspend方法的线程试图获得同一个锁,那么程序死锁。
被挂起的线程等待被恢复,将其挂起的线程等待获得锁
如果想安全地挂起(暂停)一个线程,需要引入一个变量suspendRequested,并在run方法的安全地方测试它,安全指的是同步块之外。
当该线程发现suspendRequested变量已被设置,那么会保持等待直至它再次获得为止
示例:
public class SuspendTest implements Runnable{
private volatile boolean suspendRequested = false; //指示是否要求暂停
private Lock suspendLock = new ReentrantLock();
private Condition suspendCondition = suspendLock.newCondition();
@Override
public void run() {
while(/*true*/){
//...
if(suspendRequested) {//如果请求暂停线程
suspendLock.lock();
try {
while(suspendRequested) { //当仍处于暂停状态时,await
suspendCondition.await();
}
}finally {
suspendLock.unlock();
}
}
}
}
public void requestSuspend() {
this.suspendRequested = true;
}
public void requestResume() {
this.suspendRequested = false;
suspendLock.lock();
try {
suspendCondition.signalAll();
}finally {
suspendLock.unlock();
}
}
}
await和signalAll方法都是在同步块中调用的