最好在try块内部使用synchronized块或在synchronized块内部使用try块?

时间:2013-02-18 20:15:18

标签: java multithreading try-catch synchronized-block

例如,这样更好吗?

try {
    synchronized (bean) {
        // Write something              
    }
} catch (InterruptedException e) {
    // Write something
}

或者这更好:

synchronized (bean) {
    try {           
        // Write something              
    }
    catch (InterruptedException e) {
        // Write something
    }
}

我想知道哪一个是最佳实践。显然考虑到我必须同步try块中的所有代码。我不是在谈论我只能在try中同步部分代码的情况(在这种情况下,我认为在try中包含synch块会更好)。我的疑问是关于我要同步所有try块的情况。

6 个答案:

答案 0 :(得分:11)

  

最好在try块内部使用synchronized块或在synchronized块内部使用try块吗?

除非您明确要求catch位于synchronized块中,否则我会将代码的synchronized部分尽可能小,并将其放在try / catch中。所以第一种模式会更好。然后,如果你确实需要在catch部分进行操作(比如记录异常或重新中断线程,请参见下文),这些操作不会阻止其他线程。

那就是说,如果synchronized块包含多行(当然通常不是一个好主意),那么我会考虑将try / catch块移动到更接近抛出异常的方法(prolly {{ 1}}或wait)。如果使用大量的行,则存在使用大型try / catch块不正确地处理异常的风险。在这里取决于参考框架。

另外,请确保至少记录中断的异常。永远不要忽视它们。您可能还想重新中断该线程:

notify

答案 1 :(得分:3)

没有最佳做法。它只取决于您是否需要同步块内的异常处理部分。您可能想要一个或另一个,并且应该选择使同步块最短的那个,同时仍然使代码正确且线程安全。

答案 2 :(得分:2)

你似乎认为这只是一个美学问题。事实并非如此。这是一个功能性问题,答案取决于每个案例的要求。每个同步块应该尽可能大,以包含需要同步的任何内容,并且不能更大。

答案 3 :(得分:0)

你的catch块是否同步是否重要?既然你已经“写了一些东西”,我假设你要做一些日志记录,不需要与一个好的日志框架同步,这意味着答案可能是没有

一般来说,您的目标应该是尽可能少地使用同步。同步块越小,遇到问题的可能性就越小。

答案 4 :(得分:0)

在这种情况下,InterruptedException只能在您synchronizedwaitsleep的{​​{1}}区域内发生。

通常,最佳做法是将notify块放在可能引发异常的代码附近,以便很容易识别要修复的代码。

答案 5 :(得分:0)

它与synchronized{try{}}try{synchronized{}}无关,而是与synchronized{catch{}}synchronized{} catch{}无关。这实际上取决于你在catch区块中做了什么。

但是,对InterruptedException进行猜测,您通常应该在catch{}之外synchronized{}进行猜测。