Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 计数为0时CountDownLatch Wait()上的线程被阻塞_Java_Countdownlatch - Fatal编程技术网

Java 计数为0时CountDownLatch Wait()上的线程被阻塞

Java 计数为0时CountDownLatch Wait()上的线程被阻塞,java,countdownlatch,Java,Countdownlatch,在分析其中一个生产环境的日志时,我在countdownlatch await()上看到一个线程处于“等待”状态 闩锁被初始化为1,另一个线程在闩锁的同一个实例上调用了countDown()方法,但主线程仍然在闩锁上被阻塞。这导致jvm被无限期挂起 即使闩锁计数达到零,也会被阻止,这听起来不合理,我正在寻找进一步解决此问题的建议 有什么想法吗 注意-使用的jvm版本如下 java版本“1.5.0_15” Java(TM)2运行时环境,标准版(build 1.5.0_15-b04) Java Hot

在分析其中一个生产环境的日志时,我在countdownlatch await()上看到一个线程处于“等待”状态

闩锁被初始化为1,另一个线程在闩锁的同一个实例上调用了countDown()方法,但主线程仍然在闩锁上被阻塞。这导致jvm被无限期挂起

即使闩锁计数达到零,也会被阻止,这听起来不合理,我正在寻找进一步解决此问题的建议

有什么想法吗

注意-使用的jvm版本如下

java版本“1.5.0_15” Java(TM)2运行时环境,标准版(build 1.5.0_15-b04) Java HotSpot(TM)客户端虚拟机(构建1.5.0_15-b04,混合模式,共享)

更新-下面是我在上面讨论的线程的代码片段

private class MyRunnable implements Runnable, Thread.UncaughtExceptionHandler {

        private AtomicBoolean shouldStop = new AtomicBoolean(false);
        private CountDownLatch stopLatch = new CountDownLatch(1);
        private Thread currentThread;

    public void run() {

        Thread.currentThread().setName("My Thread");
            Thread.currentThread().setUncaughtExceptionHandler(this);
            currentThread = Thread.currentThread();
            if (currentThread.isInterrupted()) {
                logger.debug("The pool thread had its interrupted stattus set. Clearing...");
                Thread.interrupted();
                logger.debug("The pool thread had its interrupted stattus set. Clearing...DONE");
            }
            try {
                doBusinessLogic(shouldStop);
            } catch (Exception e) {
                logger.error("An exception was encountered in the thread", e);
            } finally {
                if (currentThread.isInterrupted()) {
                    logger.debug("Clearing interupted status for the thread and returning to pool...");
                    Thread.interrupted();
                }
                stopLatch.countDown();
                logger.debug("Stopped task after counting down on the latch");
            }
        }

        public void stopThread() {
            shouldStop.set(true);
            logger.debug("Stop flag was set to true.. waiting for thread method to return...");
            try {
                stopLatch.await();
                logger.debug("Stop flag was set to true... task has finished. Returning.");
            } catch (InterruptedException e) {
                logger.error("Interrupted while awaiting thread stop event...", e);
            }
        }

        public void uncaughtException(Thread t, Throwable e) {
            logger.error("An uncaught exception occurred in the task thread ", e);
        }


        private void doBusinessLogic(AtomicBoolean shouldStop) {
    long sleepPeriod = 11;
    while (!shouldStop.get()) {
        try {
            Thread.sleep(sleepPeriod);
        } catch (InterruptedException e) {
            logger.debug("Thread was interrupted.Clearing interrupted status and proceeding", e);
            if (Thread.currentThread().isInterrupted())
                Thread.interrupted();
        }
        if (shouldStop.get()) {
            logger.debug("Stop flag was set. Returning.");
            return;
        }
        try {
            logger.debug("Performing business logic...");
            //.....
            logger.debug("Performing business logic...DONE");
        } catch (Throwable e) {
            logger.error("An exception occurred", e);
        }
        if (shouldStop.get()) {
            logger.debug("Stop flag was set. Returning.");
            return;
        }
    }

}


}

这是我在日志中看到的

DEBUG [main Thread] - Stop flag was set to true.. waiting for thread method to return...
DEBUG [My Thread]   - Stop flag was set. Returning.
DEBUG [My Thread]   - Stopped task after counting down on the latch

latch.await()之后的logger语句永远不会被打印,线程转储也表明主线程在latch上被阻塞。

我本想将此作为一条评论来写,但我的声誉还不允许评论,因此我将在这里提供我的一些经验


我遇到了同样的问题。我的倒计时锁存器是通过同步方法访问的:删除同步解决了问题(当然,我必须调整方法的代码以应对缺少同步的情况)。我不知道如何解释这种行为。

您说在同一个实例上调用了
countDown()
,但我更倾向于相信您的代码和诊断中比JRE库中有缺陷。你能制作一个简短但完整的程序来演示这个问题吗?如果我能演示,我可能知道根本原因:)。我之所以说countDown()被调用,是因为logger语句表明了这一点。在调用countDown()之后添加了日志语句,这些语句可以在日志中看到。线程转储表明主线程仍在等待闩锁计数为零。我敢说调用了
倒计时
,但您的日志记录是否也无可争议地表明它是在同一实例上调用的?添加代码片段以获得清晰的概念。让我知道你的建议。但是你只有一个这个类的实例吗?每个实例都有自己的锁存器,因此如果您最终在某个地方创建了一个额外的实例并意外使用了它,这就可以解释了。它被称为deadlocknop,它不是:如原始问题中所述,锁存器计数达到了0,因此没有任何东西阻塞等待的线程。然而,它并没有醒来。(据我记忆所及,这是6年前的事了……)我对您的“我的倒计时锁被同步方法访问:删除同步解决了问题(当然我必须调整方法代码以应对缺少同步的情况)。我不知道如何解释这种行为。这被称为死锁,因为任何进入同步块的人都在等待其他人进入同步块,但在该线程离开之前不能进入。。。。
DEBUG [main Thread] - Stop flag was set to true.. waiting for thread method to return...
DEBUG [My Thread]   - Stop flag was set. Returning.
DEBUG [My Thread]   - Stopped task after counting down on the latch