Pergunta

I'm trying to implement some logic when I create main(father) thread witch executes several other threads. Then it waits for some condition which child threads creates. After condition is meet the father executes some more child threads. The problem that when I use wait/notify I have java.lang.IllegalMonitorStateException exception. Here is the code:

public class MyExecutor {

final static ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(10);
final static ExecutorService svc = Executors.newFixedThreadPool(1);
static final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 8, 10, TimeUnit.SECONDS, queue);

public static void main(String[] args) throws InterruptedException {
    final MyExecutor me =  new MyExecutor();
    svc.execute(new Runnable()  {
        public void run() {
            try {
                System.out.println("Main Thread");
                me.execute(threadPool, 1);
                System.out.println("Main Thread waiting");
                wait();
                System.out.println("Main Thread notified");
                me.execute(threadPool, 2);
                Thread.sleep(100);
                threadPool.shutdown();
                threadPool.awaitTermination(20000, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });

    svc.shutdown();
    svc.awaitTermination(10000, TimeUnit.SECONDS);
    System.out.println("Main Thread finished");
}

public void execute(ThreadPoolExecutor tpe, final int id) {
    tpe.execute(new Runnable()  {
        public void run() {
            try {
                System.out.println("Child Thread " + id);
                Thread.sleep(2000);
                System.out.println("Child Thread " + id + " finished");
                notify();
            } catch (InterruptedException e) {

                e.printStackTrace();
            }
        }
    });
}

}

When I comment wait and notify line I have the following output:
Main Thread
Main Thread waiting
Main Thread notified
Child Thread 1
Child Thread 2
Child Thread 1 finished
Child Thread 2 finished
Main Thread finished

Foi útil?

Solução

There is a series of design flaws in your code:


Calling both wait() and notify() must occur only when you are the owner of the lock of the object:

synchronized(foo) {
    foo.wait();
}

You are calling wait() and notify() on different objects (inner classes!) - if one threads is waiting on one object, you must call notify on the same object.


There is a possibility of missed notify when this:

me.execute(threadPool, 1);

is called before wait - very serious bug (race condition possibility).

Others might suggest you using some higher level synchronization methods, but it is crucial to understand the basics.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top