awaitTermination函数的IllegalMonitorStateException

joz*_*ai1 10 java multithreading illegalmonitorstateexcep

我在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();
        }
Run Code Online (Sandbox Code Playgroud)

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) 
Run Code Online (Sandbox Code Playgroud)

从上面的代码调用函数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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

And*_*niy 2

Thread如果我们将您的代码包装在一些代码中,然后调用他已弃用的(仅用于演示问题)方法,则可以轻松重现此问题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();
    }
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

这是什么意思?

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

1) 你的restartMachine类已经停止了运行该应用程序的机器。这导致了JVM这样的续集停止

2)在您的应用程序中的某些地方,您在其他线程中运行提到的代码,该代码在某个地方以我所描述的方式或另一种方式停止。

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

UPD:只是另一个想法,3)如果您正在运行您的应用程序,Tomcat例如,当Tomcat停止您的应用程序时,这也可能导致此类问题。