如果我的线程在sleep()中收到InterruptedException,如何判断它是由对其.interrupt()或.notify()方法的调用引起的?
长话说:
我有一个在线程中运行的View()类。它应该运行worker并不时更新视图。它还应该衡量工人花费的时间。该View()应该可以被应用程序中断(关闭时)。工人在完成测量所花费的时间后,应在睡眠中唤醒(通知)线程。 (无需通知,所测量的时间将四舍五入到下一个不需要的完整睡眠周期。)因此,可以通过调用线程的.interrupt()或.notify()方法来触发InterruptedException。我该如何在catch块中进行区分?
public class View() implements Runnable {
Long started = null;
Long finished = null;
@Overload
public void run(){
Set<Thread> workers = new HashSet<Thread>();
for(int i = 1; i <= 5; i++){
Thread worker = new Thread(new Worker());
worker.start();
workers.add(worker);
}
started = System.getCurrentTimeMillis();
do{
try{
TimeUnit.SECONDS.sleep(3);
updateView();
}catch(InterruptedException e){
if(--> thread_was_notified <--){
finished = System.getCurrentTimeMillis();
updateView();
}
if(--> thread_was_notified <--){
for(Thread worker : workers)
worker.interrupt();
}
return;
}
}while(true);
}
protected void updateView(){
// …
}
}
我首先猜测InterruptedException会有子类,但是javadoc中没有直接已知的子类列表。线程提供
.isInterrupted()
,但as said here:“按照惯例,任何通过抛出InterruptedException退出的方法都会清除中断状态。”所以我也无法通过.isInterrupted()
告诉。干净的方法是什么?我的主意是我的代码应使用
Object.wait()
,但是等待对象是什么? 最佳答案
丑陋的解决方案:
而不是让您的Workers中断View线程,而是放置一个这样的方法:
public void workedFinished() {
interruptedByWorker = true; // View attribute.
viewThread.interrupt(); // Interrupt the view
}
然后,当您遇到问题时,请检查
interruptedByWorker
布尔值。如果属实,则被工人打断。否则(请确保发生这种情况),它已被关机中断。另一种解决方案
您可以执行以下操作,而不是在两个不同的地方中断线程(我认为这可能会使容易出错的地方造成混乱),
1)使用
Runnable
安排ScheduledExecutorService
每3秒运行一次以更新视图。2)有一个
CountdownLatch
通知每个完成的Worker。请注意,在您的代码中,第一个线程将唤醒View,这意味着所测量的时间将仅针对该线程,而不会等到其他线程完成。