0

当我创建主(父)线程女巫执行其他几个线程时,我正在尝试实现一些逻辑。然后它等待子线程创建的某些条件。满足条件后,父亲会执行更多的子线程。当我使用等待/通知时出现 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完成
主线程完成

4

1 回答 1

7

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


仅当您是对象锁的所有者时才必须调用两者wait()和:notify()

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

您正在调用不同的对象(内部类!) - 如果一个线程正在等待一个对象,则必须调用wait()同一个对象notify()notify


出现以下情况时可能会错过notify

me.execute(threadPool, 1);

之前调用过wait-非常严重的错误(可能存在竞争条件)。

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

于 2011-03-20T16:21:07.137 回答