java - awaitTermination 函数出现 IllegalMonitorStateException

标签 java multithreading illegalmonitorstateexcep

我在 Java 中使用线程时遇到问题(我在 Java 中使用线程的经验很少,但在 C++ 中使用很多,所以我了解线程的基本概念)。我已经在 J​​ava 中使用了线程的示例代码,接下来是代码:

        ExecutorService executor = Executors.newFixedThreadPool(machines.size());

        for (Machine m : machines) {
            Runnable worker = new restartMachine(m.dataformachine());
            executor.execute(worker);
        }

        executor.shutdown();
        try {
            executor.awaitTermination(15, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

restartMachine() 正在重启一些远程机器,机器没有以任何方式连接,传递给 Runnable 的数据是给定机器的 IP 地址,然后在本地执行的命令那台机器。

接下来是执行这段代码时出现的错误:

java.lang.IllegalMonitorStateException
 at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:155)
 at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1260)
 at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:460)
 at java.util.concurrent.ThreadPoolExecutor.awaitTermination(ThreadPoolExecutor.java:1471) 

从上面的代码调用函数 awaitTermination() 时抛出异常。据我所知,从我看到的各种示例来看,这段代码应该没有任何问题。

public boolean awaitTermination(long timeout, TimeUnit unit)
    throws InterruptedException {
    long nanos = unit.toNanos(timeout);
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        for (;;) {
            if (runStateAtLeast(ctl.get(), TERMINATED))
                return true;
            if (nanos <= 0)
                return false;
            nanos = termination.awaitNanos(nanos);
        }
    } finally {
        mainLock.unlock();
    }
}

Trace 表明调用函数 mainLock.unlock() 时出错; 但据我所知,只有主线程会执行该行,所以我不知道为什么我会收到 IllegalMonitorStateException,并且程序中没有关于线程的其他代码(所以我基​​本上只使用库中的代码)

如果有任何帮助,我将不胜感激,我知道关于这个问题(这个异常(exception))已经回答了很多问题,但我不知道这里的问题是什么。

最佳答案

这个问题很容易重现,如果我们将你的代码包装在一些Thread中,然后调用他deprecated(只是为了演示问题)方法stop ,例如:

  private void method() throws InterruptedException {
        Runnable runnable = new Runnable() {
            public void run() {
                ExecutorService executor = Executors.newFixedThreadPool(1);
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(10000L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });

                executor.shutdown();

                try {
                    executor.awaitTermination(3, TimeUnit.SECONDS);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        Thread thread = new Thread(runnable);
        thread.start();
        Thread.sleep(1000L);
        thread.stop();
    }

运行这段代码,我们总是得到“期望的”异常:

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:155)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1260)
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:460)
    at java.util.concurrent.ThreadPoolExecutor.awaitTermination(ThreadPoolExecutor.java:1471)
    at q29431344.TestThreads$1.run(TestThreads.java:37)
    at java.lang.Thread.run(Thread.java:724)

这是什么意思?

如果没有查看完整的项目代码(当然,我们不是在问它),很难 100% 保证发生了什么。但是有两种可能性:

1) 您的restartMachine 类已停止运行此应用程序的机器。这导致 JVM 停止执行此类续集

因此,您必须分析这些方式并了解哪些方式可能更符合您的情况。

UPD:只是另一个想法,3) 例如,如果您在 Tomcat 下运行您的应用程序,当 Tomcat 停止您的应用程序。

关于java - awaitTermination 函数出现 IllegalMonitorStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29431344/

相关文章:

java - 马文 : Does project inheritance or aggregation better support this scenario?

java - Hibernate - 软删除 - 多个参数

java - 无法从 GUI 线程获取字符串到 java 中的 'logic' 线程

Java多线程代码给出错误-Illegal Monitor Exception

java - 暂停图形?

java - 阅读java在线文档

java - Spring JpaRepositroy.save() 似乎不会在重复保存时抛出异常

python - 如何从工作线程导入 Python 异步模块?

multithreading - 如何在 Go 中安全地关闭一个 chan chan T?

Java线程从共享堆栈数组读取和写入