开发者

Threads syncronization with ThreadPoolExecutor

开发者 https://www.devze.com 2023-02-18 09:50 出处:网络
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

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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消