简体   繁体   English

在哪里使用synchronized块捕获Object.wait()的InterruptedException?

[英]Where to catch InterruptedException for Object.wait() with synchronized block?

As I understand this is very common snippet for multithreading in Java. 据我所知,这是Java中多线程的非常常见的片段。

boolean loaded = false;
Object lock = new Object();

public void block() {
    synchronized (lock) {
        while(!loaded)
            lock.wait(); // Unhandled exception type InterruptedException
    }
}

and in another thread 在另一个线程中

public void done () {
    synchronized (lock) {
        loaded = true;
        lock.notify();
    }
}

But I am not sure where I should put try and catch, I can surround whole synchronized block or only lock.wait() ? 但是我不确定我应该把try和catch放在哪里,我可以包围整个synchronized块或只有lock.wait() What is rule of thumb and does it really matter? 什么是经验法则,它真的重要吗?

For handling is it okay to call Thread.currentThread().interrupt() in this situation? 对于处理是否可以在这种情况下调用Thread.currentThread().interrupt()

You might want to consider the article by Brian Goetz: Java theory and practice: Dealing with InterruptedException 您可能想要考虑Brian Goetz撰写的文章: Java理论与实践:处理InterruptedException

In general, if you don't know what to do then don't do anything but let a caller code know that this method can be interrupted while waiting on a lock. 一般情况下,如果您不知道该怎么做,那么除了让调用者代码知道在等待锁定时可以中断此方法时,不要做任何事情。 You can do this by adding throws InterruptedException to a method signature. 您可以通过将InterruptedException抛出到方法签名来执行此操作。

If for some reason you are forced to add a try/catch block and handle the exception then Thread.currentThread().interrupt() will do but re-throwing it can be as suitable. 如果由于某种原因你被迫添加一个try / catch块并处理异常,那么Thread.currentThread()。interrupt()会做,但重新抛出它可能是合适的。

But I am not sure where I should put try and catch, I can surround whole synchronized block or only lock.wait()? 但是我不确定我应该把try和catch放在哪里,我可以包围整个synchronized块或只有lock.wait()? What is rule of thumb and does it really matter? 什么是经验法则,它真的重要吗?

lock.wait() is the only line that can throw an exception in your block method. lock.wait()是唯一可以在block方法中引发异常的行。 So whether you put your try/catch around the wait or include the whole method body does not make a difference from an execution perspective (assuming you exit the loop in both cases of course - if you want to continue looping then the try/catch block should obviously be within the loop). 因此,无论是将try / catch放在等待中还是包含整个方法体都没有区别于执行角度(假设你在两种情况下都退出循环 - 如果你想继续循环那么try / catch块显然应该在循环内)。

In other words it is only a matter of style - see this other discussion . 换句话说,这只是一种风格问题 - 请参阅其他讨论 I personally think this is more readable: 我个人认为这更具可读性:

try {
    synchronized (lock) {
        while (!loaded) {
            lock.wait(); // Unhandled exception type InterruptedException
        }
    }
} catch (InterruptedException e) {
    //to ignore me or not to ignore me, that is the question
    Thread.currentThread().interrupt();
}

For handling is it okay to call Thread.currentThread().interrupt() in this situation? 对于处理是否可以在这种情况下调用Thread.currentThread()。interrupt()?

In the first example below, it is okay to catch the InterruptedException and exit your loop without re-interrupting the thread, because in any case the run method will exit and the thread will die: 在下面的第一个例子中,可以捕获InterruptedException并退出循环而不重新中断线程,因为在任何情况下run方法都将退出并且线程将死掉:

new Thread(new Runnable() {

    @Override
    public void run() {
        block();
    }
}).start();

In the second example below, you certainly should re-interrupt the thread to let the run method know whether the reason why block() exited is that loaded became true or that it got interrupted: 在下面的第二个例子中,你当然应该重新中断线程,让run方法知道block()退出的原因是加载变为true还是被中断:

public void run() {
    while(!Thread.currentThread().isInterrupted()) {
        loaded = false;
        System.out.println("Launching data load");
        block(); //if false has become true, loop, if interrupted, exit
    }
}

If you don't know how the method will be used, good manners suggest that you should re-interrupt the thread. 如果您不知道如何使用该方法,那么良好的方式建议您应该重新中断该线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM