【问题标题】:Synchronized block and while loop optimal ordering同步块和while循环优化排序
【发布时间】:2019-07-07 06:31:01
【问题描述】:

如果我正在等待这样的条件(注意:currentAtomicIntegertargetint):

while (current.get() < target) {
    try {
        synchronized (current) {
            current.wait();
        }
    }
    catch (InterruptedException ie) {}
}

那么同步应该在while内部(如上)还是在外部,像这样?

synchronized (current) {
    while (current.get() < target) {
        try {
            current.wait();
        }
        catch (InterruptedException ie) {}
    }
}

我的问题是,上述两段代码之间的实际/功能差异是什么?什么时候应该使用另一段代码?

编辑:当另一个线程执行以下操作时退出循环

if (current.incrementAndGet() >= target) {
    synchronized (current) {
        current.notify();
    }
}

【问题讨论】:

  • 哪个线程正在递增/递减current(在代码中看不到,但必须退出循环......)?如果它是另一个线程,您可能需要检查 synchronized (current) 对其他线程上对 current.increment/decrementAndGet 的调用的影响。
  • @ernest_k 我已更新问题以显示退出条件。

标签: java concurrency synchronization synchronized


【解决方案1】:

这取决于代码的critical section 是什么,而不是最佳实践。


但是,最好将临界区代码长度保持在最短,因为您一次只允许一个线程进入它。否则,为了延伸到极端,您可以同步整个程序并使其安全。

【讨论】:

  • @SinaMadani: ...如果那个选项是正确的。
  • 虽然它减少了“临界区”的大小,但我想知道每次执行循环时重新获取锁是否有任何开销?无论哪种方式,理论上该条件最多只评估两次,所以我认为这没关系?
  • @SinaMadani:无论您在循环内部还是外部获取锁,代码复杂度都是 O(n)。可能会有开销,但不会改变 Big-O。可以肯定的是,分析您的代码并测量时间。
猜你喜欢
  • 2016-03-18
  • 1970-01-01
  • 1970-01-01
  • 2013-03-31
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2018-11-24
  • 2011-05-14
相关资源
最近更新 更多