Java并发障碍示例死锁

Java并发障碍示例死锁,java,multithreading,concurrency,synchronization,barrier,Java,Multithreading,Concurrency,Synchronization,Barrier,我试图实现自定义Barrier示例,以便进一步了解Java中的并发性。我有一个可运行的类: public class Barrier implements Runnable { private static Semaphore barrier = new Semaphore(0); private static int toWait = 5; private static int counter = 0; private static long sleepTi

我试图实现自定义
Barrier
示例,以便进一步了解Java中的并发性。我有一个可运行的类:

public class Barrier implements Runnable {

    private static Semaphore barrier = new Semaphore(0);
    private static int toWait = 5;
    private static int counter = 0;

    private static long sleepTime;

    public static int ID = 0;

    private int id = ++ID;

    public Barrier(long sleep){
        sleepTime = sleep;
    }

    @Override
    public void run() {

        try {

            Thread.sleep(sleepTime);

            counter++;
            if (counter == toWait){
                barrier.release(counter);
            }
            barrier.acquire();

            System.out.println("Thread with sleep: " + id + " proceeds");

        } catch (InterruptedException ex) {
            Logger.getLogger(Barrier.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

}
然后在
main
函数中,我创建5个线程并启动它们。在运行时,我遇到了无法解决的僵局。有人能告诉我我做错了什么吗?

请参阅文档:

获得许可证(如果有)并立即返回,将可用许可证数量减少一个

如果没有可用的许可证,则当前线程将出于线程调度目的被禁用,并处于休眠状态,直到发生以下两种情况之一:

另一个线程调用这个信号量的release()方法,当前线程下一个被分配一个许可证;或 其他线程会中断当前线程

因此,由于您要一次获取所有线程,并且没有一个线程被释放,因此它们都将保持被获取状态。也许把其中一个的计数器设为5。因此,通过这样做,您可以释放最后一个元素并移除其他元素的获取状态


编辑:哦,你的信号灯有0个许可证。为您的案例初始化为1或2。

没有相互排斥。为了解决这个问题,我需要添加另一个信号量,并用该信号量的
acquire
release
来包围计数器增量。

计数器
需要是一个原子整数<代码>睡眠时间不应是静态的。