线程与ThreadPoolExecutor同步

Big*_*der 0 java multithreading notify wait

我正在尝试实现一些逻辑,当我创建主(父)线程时,执行其他几个线程.然后它等待子线程创建的某些条件.在条件满足后,父亲执行更多的子线程.我在使用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();
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

}

当我评论等待和通知行我有以下输出:
主线程
主线程等待
主线程通知
子线程1
子线程2
子线程1完成
子线程2完成
主线完成

Tom*_*icz 7

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


调用两者wait()并且notify()必须仅在您是对象锁的所有者时才发生:

synchronized(foo) {
    foo.wait();
}
Run Code Online (Sandbox Code Playgroud)

要调用wait()notify()不同对象(内部类!) -如果一个线程是一个对象上等待,你必须调用notify同一对象.


这有可能错过notify:

me.execute(threadPool, 1);
Run Code Online (Sandbox Code Playgroud)

之前被称为wait- 非常严重的错误(竞争条件可能性).

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