NotifyAll, IllegalMonitorStateException

import java.math.BigInteger;

class Numbers {

    final static int NUMBER = 2;
    final static int POWER = 4;

    static long msecs;
    static BigInteger result;
    static Boolean done = false;

    public static void main(String[] args) {

        BigInteger number = BigInteger.valueOf(NUMBER);
        result = number;

        //Boolean done = false;

        Runnable pow = () -> {
            System.out.println(number + " pow " + POWER + " = " + number.pow(POWER));

            synchronized (done) {
                done = true;
                done.notifyAll();
            }
        };

        Runnable sum = () -> {
            for(int i = 2; i<POWER; i=i*i) {
                result = result.multiply(result);
            }

            System.out.println(number + " sum " + POWER + " = " + result);

            synchronized (done) {
                done = true;
                done.notifyAll();
            }
        };

        Runnable time = () -> {
            for(msecs = 0; true; msecs++) {
                try {
                    Thread.sleep(1);
                } catch(InterruptedException e) {
                    //nic
                }
            }
        };

        Thread timet = new Thread(time);
        Thread sumt = new Thread(sum);
        Thread powt = new Thread(pow);

        timet.start();
        powt.start();

        synchronized (done) {
            while(!done) {
                try {
                    done.wait();
                } catch (InterruptedException e) {
                    //nic
                }
            }
        }

        timet.interrupt();
        powt.interrupt();

        System.out.println("Pow time " + msecs + " msecs.");
        done = false;

        timet.start();
        sumt.start();

        try {
            synchronized (done) {
                while (!done) {
                    done.wait();
                }
            }
        } catch (InterruptedException e) {
            //nic
        }


        timet.interrupt();
        sumt.interrupt();

        System.out.println("Sum time " + msecs + " msecs.");

    }
}

I want to check the time difference between the two methods, but done.notifyAll()continues to throw IllegalMonitorStateException.

+4
source share
2 answers

The problem is here:

synchronized (done) {
    done = true;//<---problem
    done.notifyAll();
}

Since you are assigning a new value done, this means that you are running notifyAllon Boolean.TRUE, but your synchronization unit is using a monitor Boolean.FALSE. And since it notifyAllrequires that the thread has a monitor of the object on which it is running, it throws IllegalMonitorStateException.

, . , ( /), , ​​ , , .

, . Jon Skeet ( lockObject ?)

private final Object lock = new Object();
+8

, , .... Java- Object.notifyAll()

IllegalArgumentException - if the value of timeout is negative. IllegalMonitorStateException - if the current thread is not the owner of the object monitor. InterruptedException - if any thread interrupted the current thread before or while the current thread was waiting for a notification. The interrupted status of the current thread is cleared when this exception is thrown.

, , Object, . : a private final Object doneLock = new Object(). Done doneLock. , , .

,

synchronize(doneLock) {
    done = true;
    doneLock.notifyAll();
}
+3

Source: https://habr.com/ru/post/1624876/


All Articles