java – IllegalMonitorStateException on awaitTermination函数

前端之家收集整理的这篇文章主要介绍了java – IllegalMonitorStateException on awaitTermination函数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在 Java中使用线程有一个问题(我对Java中的线程没有经验,但是在C中很多,所以我理解线程的基本概念).我在Java中使用线程的示例代码,代码如下:
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();
    }
}

跟踪指示错误调用函数mainLock.unlock();
但是据了解,只有主线程将执行该行,所以我不知道为什么我得到IllegalMonitorStateException,并没有其他代码关于程序中的线程(所以我基​​本上只使用库中的代码)

我会感谢任何帮助,我知道有很多问题已经回答了这个问题(这个例外),但我不知道这里是什么问题.

解决方法

这个问题可以很容易地被复制,如果我们将你的代码封装在一些Thread中,然后再调用他不推荐(仅仅是为了演示问题)方法停止,例如:
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停止这样的续集

2)在你的应用程序中,你运行的一些在其他线程中提到的代码,哪个地方被阻止了我已经描述的方式或另一个.

所以,你必须分析这些方式,并了解什么可能更像你的情况.

UPD:另一个想法,3)如果您在Tomcat下运行应用程序,这也可能导致Tomcat停止应用程序时出现这样的问题.

猜你在找的Java相关文章