21

例如,这样更好吗?

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

或者最好这样:

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

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

4

6 回答 6

14

最好在 try 块内有一个同步块,还是在同步块内有一个 try 块?

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

也就是说,如果synchronized块包含许多行(当然通常不是一个好主意),那么我会考虑将 try/catch 块移到更靠近引发异常的方法(prollywaitnotify)。对于大量的行,您会冒着用大的 try/catch 块来不正确地处理异常的风险。取决于这里的参考框架。

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

try {
   ...
} catch (InterruptedException e) {
   // always a good pattern
   Thread.currentThread().interrupt();
   // handle the interrupt here by logging or returning or ...
}
于 2013-02-18T20:19:13.923 回答
3

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

于 2013-02-18T20:20:30.243 回答
2

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

于 2013-02-18T23:02:22.983 回答
0

你的 catch 块是否同步有关系吗?由于您在那里“写了一些东西”,我假设您将进行一些日志记录,这些日志记录不需要与一个好的日志记录框架同步,这意味着答案可能是否定的。

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

于 2013-02-18T20:19:55.720 回答
0

在这种情况下,InterruptedException可能只发生synchronized在您可以调用waitorsleep或的块内notify

一般来说,最好的做法是将try/catch块放置在尽可能靠近可能引发异常的代码的位置,以便于识别要修复的代码。

于 2013-02-18T20:20:44.030 回答
0

synchronized{try{}}它与or无关try{synchronized{}},但与synchronized{catch{}}or完全有关synchronized{} catch{}。这实际上取决于您在 catch 块中执行的操作。

但是,猜测一下,因为InterruptedException,你通常应该在catch{}外面做synchronized{}

于 2013-02-18T20:33:55.023 回答