[英]It is better to have a synchronized block inside a try block or a try block inside a 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 内有同步块会更好)。 我怀疑我必须同步所有 try 块的情况。
最好在try块内部使用synchronized块或在synchronized块内部使用try块?
除非你明确需要catch
在synchronized
块中,否则我会使代码的synchronized
部分尽可能小,并将它放在try / catch中。 所以第一种模式会更好。 然后,如果你确实需要在catch
部分进行操作(比如记录异常或重新中断线程,见下文),这些就不会阻塞其他线程。
也就是说,如果synchronized
块包含多行(当然通常不是一个好主意),那么我会考虑将try / catch块移动到更接近抛出异常的方法( wait
或notify
)。 如果使用大量的行,则存在使用大型try / catch块不正确地处理异常的风险。 在这里取决于参考框架。
另外,请确保至少记录中断的异常。 永远不要忽视它们。 您可能还想重新中断该线程:
try {
...
} catch (InterruptedException e) {
// always a good pattern
Thread.currentThread().interrupt();
// handle the interrupt here by logging or returning or ...
}
没有最好的做法。 它只取决于您是否需要同步块内的异常处理部分。 您可能想要一个或另一个,并且应该选择使同步块最短的那个,同时仍然使代码正确且线程安全。
你似乎认为这只是一个美学问题。 事实并非如此。 这是一个功能性问题,答案取决于每个案例的要求。 每个同步块应该尽可能大,以包含需要同步的任何内容,而不是更大。
你的catch块是否同步是否重要? 既然你已经“写了一些东西”,我假设你要做一些日志记录,不需要与一个好的日志框架同步,这意味着答案可能不是 。
通常,您的目标应该是尽可能少地使用同步。 同步块越小,遇到问题的可能性就越小。
在这种情况下, InterruptedException
只能在synchronized
块中发生,您可以在其中调用wait
或sleep
或notify
。
通常,最佳做法是将try/catch
块放在可能引发异常的代码附近,以便很容易识别要修复的代码。
它与synchronized{try{}}
或try{synchronized{}}
无关,但与synchronized{catch{}}
或synchronized{} catch{}
。 这实际上取决于你在catch块中做了什么。
但是,猜测一下,对于InterruptedException
,你通常应该在synchronized{}
之外catch{}
synchronized{}
。
这太旧了,但我今天正在审查一个初级同事的代码,我发现了一个与使用 Java 锁 object 相关的巨大错误,就像它是一个同步块一样。 我正在寻找一些关于 Java 同步不完美的文档,只是遇到了这个并考虑离开我的解决方案:
在同步的情况下,这真的取决于你的逻辑,因为 java 保证了锁的解放。
但是,当您使用基于 Object 的锁时,例如 java 的 ReentrantLock,您必须始终执行以下操作:
private final ReentrantLock lock = new ReentrantLock ();
void foo() {
lock.lock();
try {
// Do your things
} finally {
lock.unlock();
}
}
一旦你有了这个结构来确保锁释放,你可以将锁和整个 try/finally 都封装到另一个 try 中,如果你不想在锁边处理 catch 的话,或者把它放在哪里 // 如果你想做你的事情从内部处理它。
另外,请记住,java 锁并不完美,就像在任何编程语言中一样,锁类型的选择取决于底层语言,操作的关键程度(如果锁失败,有人会死,或者受控软件一百万次重试一次就行了?)和锁的性能影响。
如果您对锁一无所知,我建议您学习以下概念:
大多数时候,您真正需要的是信号量、多读单写锁或只是一个监视器,因此了解这些术语可以让您更快地搜索所需内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.