同步方法

发布于 2024-10-27 19:56:39 字数 175 浏览 1 评论 0原文

如果我有一个同步的公共方法和一个私有方法:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

┈┾☆殇 2024-11-03 19:56:39

这取决于:

  • 如果 doSomethingElse 可以安全地并发调用,那么您就不需要 synchronized
  • 如果不是,那么答案取决于调用它的位置:
    • 如果仅从其他synchronized方法调用它,则不需要synchronized(但将其标记为这样不会有什么坏处);
    • 如果可以从本身不同步的方法调用它,那么它必须同步

It depends:

  • If doSomethingElse is safe to call concurrently, then you don't need synchronized.
  • If it isn't, then the answer depends on where it is called from:
    • If it is only called from other synchronized methods, then it doesn't need to be synchronized (but marking it as such will do no harm);
    • If it can be called from methods that aren't synchronized themselves, then it must be synchronized.
寄居人 2024-11-03 19:56:39

这取决于你在做什么。您是否需要确保对 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() is doSomething(), then no, you don't need to synchronize. But if some other method can call doSomethingElse(), then yes, you should synchronize it also.

节枝 2024-11-03 19:56:39

否:如果调用 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.

辞取 2024-11-03 19:56:39

这就是 @GuardedBy 注释的目的。如果您期望在调用该方法时必须持有锁,请用该锁和锁的名称对其进行注释(在示例中为:

@GuardedBy("this") private void doSomethingElse() {…}

然后您可以使用 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:

@GuardedBy("this") private void doSomethingElse() {…}

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.

栖迟 2024-11-03 19:56:39

从同步方法(或从 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.

寂寞清仓 2024-11-03 19:56:39

如果同步一个代码块,那么从该代码块内(在同一线程上)调用的任何内容仍然保留初始锁。因此,当从 doSomething 调用时,doSomethingElse 仍然是同步块的一部分。

如果您这样做:

public synchronized void doSomething() {
  new Thread() {
    public void run() {
      doSomethingElse();
    }
  }.start();
}
private void 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 from doSomething.

If you did:

public synchronized void doSomething() {
  new Thread() {
    public void run() {
      doSomethingElse();
    }
  }.start();
}
private void doSomethingElse() {
}

Then doSomethingElse would not have the lock that was acquired by doSomething.

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 from doSomething, it wouldn't hurt to synchronize doSomethingElse as synchronized locks are re-entrant (i.e., if a thread already has a lock on an object it can get the lock again).

猥琐帝 2024-11-03 19:56:39

就我个人而言,我不喜欢同步方法。我更喜欢与某种锁变量同步,如下所示:

private final Object lock = new Object();

public void doSomething() {
  synchronized(lock) {
    // Do some safely
    doSomethingElse();
  }
  // Do some work un-safely
}

private void doSomethingElse() {
  // Do some work safely because still in lock above
  // ...
}

Personally, I do not like synchronized methods. I prefer to synchronize with some kind of lock varaible, as so:

private final Object lock = new Object();

public void doSomething() {
  synchronized(lock) {
    // Do some safely
    doSomethingElse();
  }
  // Do some work un-safely
}

private void doSomethingElse() {
  // Do some work safely because still in lock above
  // ...
}
漫漫岁月 2024-11-03 19:56:39

尽管您所做的很好,但在我看来,同步应该以尽可能低的粒度完成。这建议同步实际的私有函数。目前,您假设类中没有其他函数会独立调用私有函数。未来可能不会出现这种情况。

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.

剧终人散尽 2024-11-03 19:56:39

尽管在私有方法未同步时代码可以正常工作,但从可维护性的角度来看,使私有方法同步似乎是谨慎的做法。

内在锁是可重入的,在私有方法中添加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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文