线程与ThreadPoolExecutor同步

时间:2011-03-20 16:06:01

标签: java multithreading wait notify

当我创建主(父)线程时,我正在尝试实现一些逻辑,以执行其他几个线程。然后它等待子线程创建的某些条件。在条件满足后,父亲执行更多的子线程。 我在使用wait / notify时遇到java.lang.IllegalMonitorStateException异常的问题。这是代码:

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();
            }
        }
    });
}

}

当我评论等待并通知行时,我有以下输出:
主线
主线等待
主线通知
儿童线程1
儿童线程2
儿童线程1完成了 儿童线程2完成了 主线完成了

1 个答案:

答案 0 :(得分:7)

您的代码中存在一系列设计缺陷:


只有当您是对象锁定的所有者时,才必须同时调用wait()notify()

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

你在不同的对象(内部类!)上调用wait()notify() - 如果一个线程在一个对象上等待,你必须在相同<上调用notify / strong>对象。


这可能会错过notify

me.execute(threadPool, 1);
wait - 非常严重错误(竞争条件可能性)之前调用

其他人可能会建议您使用一些更高级别的同步方法,但了解基础知识至关重要。