同步方法
如果我有一个同步的公共方法和一个私有方法:
public synchronized void doSomething() {
doSomethingElse()
}
private void doSomethingElse() {
}
我需要同步私有方法吗?
If I have a synchronized public method and a private method:
public synchronized void doSomething() {
doSomethingElse()
}
private void doSomethingElse() {
}
Do I need to synchronize the private method?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
这取决于:
doSomethingElse
可以安全地并发调用,那么您就不需要synchronized
。synchronized
方法调用它,则不需要synchronized
(但将其标记为这样不会有什么坏处);同步
的方法调用它,那么它必须是同步
。It depends:
doSomethingElse
is safe to call concurrently, then you don't needsynchronized
.synchronized
methods, then it doesn't need to besynchronized
(but marking it as such will do no harm);synchronized
themselves, then it must besynchronized
.这取决于你在做什么。您是否需要确保对
doSomethingElse()
的串行访问?如果是这样,并且唯一调用
doSomethingElse()
的是doSomething()
,那么不,您不需要同步。但如果其他方法可以调用 doSomethingElse(),那么是的,您也应该同步它。It depends on what you're doing. Do you need to ensure serial access to
doSomethingElse()
?If so, and the only thing calling
doSomethingElse()
isdoSomething()
, then no, you don't need to synchronize. But if some other method can calldoSomethingElse()
, then yes, you should synchronize it also.否:如果调用
doSomethingElse()
的唯一方法是通过另一个同步方法。可能是:如果您以其他方式通过未同步的方法调用
doSomethingElse()
,则需要保护它免受并发访问。NO: if the only way
doSomethingElse()
is called is through another method that IS synchronized.Possibly YES: If you call
doSomethingElse()
in some other fashion, through a method that is not synchronized, and you need to protect it against concurrent access.这就是
@GuardedBy
注释的目的。如果您期望在调用该方法时必须持有锁,请用该锁和锁的名称对其进行注释(在示例中为:然后您可以使用 FindBugs 检查不变量是否为 true 您还可以
使用其他
net.jcip.annotations
用于描述线程安全性或缺乏线程安全性,并让 FindBugs 也验证这些假设,这本书也需要一个插头。This is the intent of the
@GuardedBy
annotation. If you expect that a lock must be held when calling that method, annotate it with that and the name of the lock (in the example it would be:Then you can check that the invariant is true with FindBugs.
You can also use the other
net.jcip.annotations
for describing the thread-safety or lack of it and have FindBugs validate these assumptions too. Of course, the book needs a plug as well.从同步方法(或从
synchronized
块内)调用的任何方法都会在同步时运行。如果仅从同步方法调用私有方法,则无需单独同步该私有方法。Any methods called from a synchronized method (or from within a
synchronized
block) are run while still synchronized. You don't need to separately synchronize the private method if it is only called from synchronized methods.如果同步一个代码块,那么从该代码块内(在同一线程上)调用的任何内容仍然保留初始锁。因此,当从
doSomething
调用时,doSomethingElse
仍然是同步块的一部分。如果您这样做:
那么
doSomethingElse
将不会拥有由doSomething
获取的锁。还要避免同步方法,因为它会公开并发策略的实现细节。请参阅有关同步(this)/同步方法的问题:在 Java 中避免同步(this)?
如果
doSomethingElse
必须同步,无论它是否是从doSomething
调用的,同步doSomethingElse
也没有坏处,因为同步锁是可重入(即,如果一个线程已经拥有一个对象的锁,它可以再次获得该锁)。If you synchronize a block of code then anything called from within that block of code (on the same thread) still holds the initial lock. So
doSomethingElse
is still a part of the synchronized block when it is called fromdoSomething
.If you did:
Then
doSomethingElse
would not have the lock that was acquired bydoSomething
.Also avoid synchronized methods as it exposes the implementation details of your concurrency policy. See this question on synchronized(this) / synchronized methods: Avoid synchronized(this) in Java?
If
doSomethingElse
must be synchronized, regardless of whether or not it is called fromdoSomething
, it wouldn't hurt to synchronizedoSomethingElse
as synchronized locks are re-entrant (i.e., if a thread already has a lock on an object it can get the lock again).就我个人而言,我不喜欢同步方法。我更喜欢与某种锁变量同步,如下所示:
Personally, I do not like synchronized methods. I prefer to synchronize with some kind of lock varaible, as so:
尽管您所做的很好,但在我看来,同步应该以尽可能低的粒度完成。这建议同步实际的私有函数。目前,您假设类中没有其他函数会独立调用私有函数。未来可能不会出现这种情况。
Although what you've done is fine, in my opinion, synchronization should be done at the lowest granularity possible. Which would suggest to synchronize the actual private function. Currently, you're assuming that no other function in the class will call the private function independently. This may not be the case in the future.
尽管在私有方法未同步时代码可以正常工作,但从可维护性的角度来看,使私有方法同步似乎是谨慎的做法。
内在锁是可重入的,在私有方法中添加synchronized关键字没有什么坏处。
将代码放入私有方法中会导致其他方法调用它,因此使私有方法同步是有意义的,以防将来从另一个不需要同步的方法调用它。
Even though the code works correctly when the private method is not synchronized, it would seem prudent from a maintainability perspective to make the private method synchronized.
Intrinsic locks are re-entrant, there is no harm in adding the synchronized keyword to the private method.
Putting code in a private method invites letting it be called by other methods, so it would make sense to make the private method synchronized in case in the future it is called from another method that does not otherwise need to be synchronized.