从InterruptedException中查明原因

时间:2013-11-20 10:22:12

标签: java multithreading

如果我的线程在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(),但是等待对象是什么?

2 个答案:

答案 0 :(得分:1)

丑陋的解决方案:

不要让您的Workers中断View线程,而是放置一个这样的方法:

public void workedFinished() {
  interruptedByWorker = true; // View attribute.
  viewThread.interrupt(); // Interrupt the view
}

然后,当你捕获时,检查interruptedByWorker布尔值。如果是真的,那就被工人打断了。否则(确保发生这种情况),它被关闭中断。

其他解决方案 您可以执行以下操作,而不是在两个不同的地方中断线程(我认为这可能会使容易出错):

1)使用Runnable安排ScheduledExecutorService每3秒运行一次以更新视图。 2)为每个完成的工作人员通知CountdownLatch。请注意,在您的代码中,第一个线程唤醒了View,这意味着测量的时间仅适用于该线程,它不会等到其他线程完成。

答案 1 :(得分:0)

InterruptedException仅在某些线程中断您时被抛出,而在退出wait()时不会抛出。

因此当你在sleep()wait()并且其他一些线程决定打断你时,将抛出异常。

当一个线程处于wait()状态并且为它调用notify()时,它将再次获取锁并恢复其工作而不会抛出任何异常。

相关问题