问题——昨天被问到了一个具体的问题,大致是这样的:一个构建工具,在构建过程中,主要业务处理逻辑由很多的子线程去执行(嗯,大致是这个意思),然后现在客户提出了一个需求,就是要暂停构建,而是否暂停时另一个子线程去配置文件或者数据库读的,然后就需要暂停或者恢复其他执行的线程。
首先想到的是将所有子线程放到线程组中去,方便管理,然后再每个线程中去设置一个标志flag,来调用监视器对象的wait方法来暂停线程,但是立马就发现问题了
public void run() {
synchronized (control) {
while (true) {
if(flag){
try {
control.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
doingSomething();
//这里是这个线程处理业务逻辑的地方
//但是如果在这里阻塞了,就无法到判断是否暂停的逻辑上去
//所以这个暂停不是实时的
}
}
}
所以如果要调用wait和标志位的方法来中断线程的话,肯定不是实时的,有可能业务已经处理完了,你的wait也就没有意义了。
但是wait 会释放对象的锁,但是suspend()方法不会释放所持有对象的锁(监视器),例如如果在doingSomething()中持有System.out对象的锁,然后其他线程想打印写什么,就会产生阻塞,最坏的结果就是死锁。
Thread.suspend()方法是java调用系统方法挂起线程,同样resume()也是调用系统的方法恢复线程
所以想要做到实时暂停线程和恢复线程,就需要调用Thread的suspend()和resume()两个函数,但是要很好的分析业务逻辑中持有的对象,是不是其他未暂停线程也要访问的,避免引发死锁或者阻塞。