【问题标题】:Java concurrency barrier example deadlockJava并发屏障示例死锁
【发布时间】:2018-10-11 07:42:17
【问题描述】:

我正在尝试实现自定义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 个线程并启动它们。在运行时,我遇到了僵局,我无法解决。谁能告诉我我做错了什么?

【问题讨论】:

  • counter 需要是一个原子整数。 sleepTime 不应该是静态的。

标签: java multithreading concurrency synchronization barrier


【解决方案1】:

查看文档:

获取一个许可证,如果一个可用并立即返回,将可用许可证的数量减少一个。

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

其他一些线程为此信号量调用 release() 方法,并且当前线程接下来被分配一个许可;要么 其他一些线程中断当前线程。

因此,由于您对所有线程进行了一次aquire,并且没有一个线程被释放,因此它们都将保持被获取状态。也许将其中的 Counter on 设置为 5。因此,您可以释放最后一个元素并通过执行此操作删除其他元素的获取状态。

编辑:哦,您的信号量有 0 个许可。根据您的情况使用 1 或 2 对其进行初始化。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-08
      • 1970-01-01
      • 1970-01-01
      • 2012-10-30
      • 1970-01-01
      • 2018-12-20
      • 2019-10-18
      • 2012-04-07
      相关资源
      最近更新 更多