Java 当通过的线程数量小于屏障限制时,屏障(例如CyclicBarrier)是否会导致死锁?

Java 当通过的线程数量小于屏障限制时,屏障(例如CyclicBarrier)是否会导致死锁?,java,multithreading,concurrency,barrier,Java,Multithreading,Concurrency,Barrier,运行以下代码时,2个启动线程将被CyclicBarrier*对象锁定,并等待第三个线程无限期解锁 import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class MainDeadlock { public static void main(String[] args) throws InterruptedException { fi

运行以下代码时,2个启动线程将被
CyclicBarrier
*对象锁定,并等待第三个线程无限期解锁

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class MainDeadlock {
  public static void main(String[] args) throws InterruptedException {
    final CyclicBarrier c = new CyclicBarrier(3); 
    Runnable r = () -> {
            try {
                c.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println("Run!");
    };
    new Thread(r).start();
    new Thread(r).start();
}
}

因此,2个已启动线程正在等待第三个线程解决此障碍。但是,根据的Java API文档,
CyclicBarrier

一种同步辅助工具,允许一组线程都等待对方到达一个共同的障碍点

我对他们如何“互相等待”感到困惑


问题:“互相等待”是否意味着循环等待?如果是,怎么做?严格地说,这是一种死锁情况吗?

从技术上讲,这不是死锁,因为已经在屏障上的两个线程没有被对方阻塞,它们正在等待第三个永远不会到达的线程

但最终的结果与僵局非常相似,一开始可能会令人困惑

措辞也有点混乱,因为从技术上讲,在限制
n
的循环屏障上,第一个
n-1
线程正在等待第n个
线程


但这与死锁之间的关键区别在于如何解决它们:线程太少的循环障碍将通过更多线程到达而得到解决,在死锁中,唯一的“解决方案”是杀死一个已经等待的线程。

你可以将
CyclicBarrier
视为根本不了解线程本身。你可以这样想:

  • 屏障会记录调用
    wait()
    的次数
  • 调用
    await()
    时,代码会阻塞(方法不会返回),但屏障会增加计数
  • 当计数达到构造时给出的
    parties
    值时,计数被重置,在调用
    await()
    时被阻塞的所有线程被释放(即方法返回)
  • 因此,在您的情况下,对
    await()
    的调用在第三次调用发生之前不会返回,因此您现有的两个线程实际上被卡住了。从技术上讲,这不是死锁,因为它可以很容易地摆脱(通过再次调用
    await()


    它被称为循环的原因是,一旦理货被重置,线程被释放,它就可以再次使用。典型的用法是将
    参与方
    设置为要在其上同步的线程数,这些线程都会进入某种循环,其中,屏障用于确保在所有其他线程也完成当前迭代之前,没有线程移动到下一个迭代。

    关于将某个情况视为死锁所需的循环等待条件:

    每个进程都必须等待由 另一个进程,它依次等待第一个进程启动 释放资源。一般来说,有一组等待过程, P={P1,P2,…,PN},这样P1正在等待由 P2、P2正在等待由P3持有的资源,依此类推,直到PN被释放 正在等待P1持有的资源

    您有一组进程P1和P2。他们在等待一些东西,但他们并不等待P3,因为不存在这样的过程。所以这并不是因为这个原因导致的僵局

    它也不满足以下条件:

    挂起并等待或资源挂起:进程当前正在挂起 至少一个资源并请求正在使用的其他资源 由其他进程持有


    (我的重点)。您没有任何进程持有任何资源,因为第三个进程不存在。

    我建议您进一步阅读死锁。这不是一个。是否因为不正确地使用同步辅助工具而导致所有线程无限期地等待?对这和僵局一样吗?不。这一个更复杂,因为我不知道
    CyclicBarrier
    的实现。最终结果是否相似并不重要(
    while(true);
    具有相似的最终结果…,“死锁”有一个非常具体的定义,但这并不满足它。@Michael确切地说。这只是因为它是问题中混乱的根源之一。