2011-03-20 86 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