【问题标题】:Threads syncronization with ThreadPoolExecutor与 ThreadPoolExecutor 的线程同步
【发布时间】:2011-03-20 16:06:01
【问题描述】:

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

【问题讨论】:

    标签: java multithreading wait notify


    【解决方案1】:

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


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

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

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


    有可能错过notify

    me.execute(threadPool, 1);
    

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

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

    【讨论】:

    • +1 我试图想办法向他们解释这一点,因为提供的代码太不正常了。
    • 谢谢。它现在正在使用 synchronized(svc) { svc.notify(); }
    • @Brian Roach:不幸的是wait/notify 结构非常脆弱和冗长,很多地方都会出错。 @justme1 考虑使用一些专用对象(final Object lock = new Object())来锁定或锁定MyExecutor(当您摆脱所有静态时)。为了我们双方的利益,请接受答案:-)。
    • 我也会试试这个方法。谢谢
    • 静态只是为了快速模拟我不会完全按照它使用代码。 :)
    猜你喜欢
    • 1970-01-01
    • 2011-07-27
    • 2013-03-18
    • 1970-01-01
    • 2015-09-20
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多