Java 从中断异常中找出原因
如果我的线程在sleep()中接收到InterruptedException,我如何判断它是由对其.interrupt()或.notify()方法的调用引起的 长话短说: 我有一个View()类在线程中运行。它应该运行worker并不时更新视图。它还应该测量工人花费的时间。View()应该可以被应用程序中断(在关闭时)。工作人员应在完成测量所用时间后,在睡眠期间唤醒(通知)线程。(在没有通知的情况下,测量的时间将被四舍五入到下一个不需要的完整睡眠周期。)因此,可以通过调用线程的.interrupt()或.notify()方法来触发InterruptedException。我如何在挡块内区分这一点Java 从中断异常中找出原因,java,multithreading,Java,Multithreading,如果我的线程在sleep()中接收到InterruptedException,我如何判断它是由对其.interrupt()或.notify()方法的调用引起的 长话短说: 我有一个View()类在线程中运行。它应该运行worker并不时更新视图。它还应该测量工人花费的时间。View()应该可以被应用程序中断(在关闭时)。工作人员应在完成测量所用时间后,在睡眠期间唤醒(通知)线程。(在没有通知的情况下,测量的时间将被四舍五入到下一个不需要的完整睡眠周期。)因此,可以通过调用线程的.interrup
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(){
// …
}
}
public class View()实现可运行{
长启动=空;
Long finished=null;
@超载
公开募捐{
Set workers=new HashSet();
对于(int i=1;i thread\u was\u notified thread\u notifiedInterruptedException
仅在某些线程中断时抛出,而在退出wait()
时不会抛出
所以,当您处于sleep()
或wait()
状态,并且其他线程决定中断您时,将抛出异常
当线程处于wait()
状态并为其调用notify()时,它将再次获取锁并恢复其工作,而不会引发任何异常。丑陋的解决方案:
与其让工作人员中断视图线程,不如使用如下方法:
public void workedFinished() {
interruptedByWorker = true; // View attribute.
viewThread.interrupt(); // Interrupt the view
}
然后,在捕获时,检查interruptedByWorker
布尔值。如果为真,则它被一个worker中断。否则(确保发生这种情况),它被关机中断
另一种解决方案
您可以执行以下操作,而不是在两个不同的位置中断线程(我认为这可能会让容易出错的人感到困惑):
1) 使用ScheduledExecutorService
更新视图,将Runnable
计划为每3秒运行一次。
2) 请注意,在您的代码中,first线程唤醒视图,这意味着测量的时间将仅用于该线程,它不会等待其他线程完成。忘记丑陋的解决方案;CountdownLatch
似乎正是我在这里需要的。这样,中断可以被限制为应用程序关闭,这是一个明确的设计。它甚至比我想的更好:countdownLatch。Wait(long,TimeUnit)返回布尔值,因此区分可能的情况。甚至不必检查计数,这也是可能的。非常感谢!