11

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 が発生するのかわかりません。また、プログラム内のスレッドに関する他のコードはありません (したがって、基本的にライブラリのコードのみを使用しています)。

この問題(この例外)に関してすでに多くの質問が回答されていることは知っていますが、ここで何が問題なのかわかりません。

4

2 に答える 2