2011-03-20 57 views
0

我试图实现一些逻辑,当我创建主(父)线程女巫执行其他线程。然后它等待一些子线程创建的条件。条件满足后,父亲执行一些更多的子线程。 当我使用等待/通知我有java.lang.IllegalMonitorStateException异常的问题。下面是代码:线程与ThreadPoolExecutor同步

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
子线程
子线程1完成
子线程2完成
主线程完成

回答

7

。在你的代码了一系列的设计缺陷:


调用都wait()notify()只有当你是对象的锁的所有者必须发生:

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

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


有错过notify的可能性时,这样的:

me.execute(threadPool, 1); 

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

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

+0

+1我试图找出一种方法来解释给他们,因为提供的代码是如此的不合时宜。 – 2011-03-20 16:24:49

+0

谢谢。它正在与同步(svc)工作{ \t \t \t \t \t svc.notify(); \t \t \t \t \t} – BigWonder 2011-03-20 16:45:26

+0

@Brian Roach:不幸的是'wait/notify'结构非常脆弱和冗长,很多地方犯了一个错误。 @ justme1考虑使用一些专用对象('final Object lock = new Object()')来锁定或锁定MyExecutor(当你摆脱所有静态的时候)。请接受我们两人的利益答案:-)。 – 2011-03-20 16:59:40