等待递归的Thread-Producer

我有一个收集者,在游戏中搜索动作。 我在一个递归搜索中搜索,以从游戏中获得所有可能的移动。

出于性能原因,我使用了一个Threadpool,并且每个找到的移动都会向池中添加一个新的Thread,以延长旧的移动。

这是一些代码:

protected static List threads; private static ExecutorService threadPool; protected final synchronized void hookThread(Runnable thread) { if (threadPool == null) { threadPool = Executors.newFixedThreadPool(15); threads = new ArrayList(); } threadPool.execute(thread); threads.add(thread); } protected abstract class GathererRunnable implements Runnable { @Override public final void run() { onRun(); threads.remove(this); } public abstract void onRun(); } 

这是父类的片段。 现在来了孩子,寻找动作。

 private void extendMove(final byte[] stones, final ByteLayMove move) { Runnable r = new GathererRunnable() { @Override public void onRun() { // fancy search stuff if (moveIsFound) extendMove(...); } }; hookThread(r); } 

现在的问题是,我不知道如何等待线程完成。

我试图使用一个int,它可以计算线程创建并减少线程完成,但这也导致了过早的搜索流产。

你有没有想法是否有一个很好的方式来等待这些线程? 我已经考虑过BlockingQueue,但我不知道如何正确实现它。

问凯文

下面的程序使用BlockingQueue实现了生产者消费者场景,你可以在编写自己的实现时使用这种方法。

 import java.util.concurrent.*; public class ThreadingExample { public static void main(String args[]){ BlockingQueue blockingQueue = new ArrayBlockingQueue(100); ExecutorService exec = Executors.newCachedThreadPool(); exec.execute(new Producer(blockingQueue)); exec.execute(new Consumer(blockingQueue)); } } class Message{ private static int count=0; int messageId; Message(){ this.messageId=count++; System.out.print("message Id"+messageId+" Created "); } } class Producer implements Runnable{ private BlockingQueue blockingQueue; Producer(BlockingQueue blockingQueue){ this.blockingQueue=blockingQueue; } @Override public void run(){ while(!Thread.interrupted()){ System.out.print("Producer Started"); try { blockingQueue.put(new Message()); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Producer Done"); } } } class Consumer implements Runnable{ private BlockingQueue blockingQueue; Consumer(BlockingQueue blockingQueue){ this.blockingQueue=blockingQueue; } @Override public void run(){ while(!Thread.interrupted()){ System.out.print("Concumer Started"); try{ Message message = blockingQueue.take(); System.out.print("message Id"+message.messageId+" Consumed "); } catch(InterruptedException e){ e.printStackTrace(); } System.out.println("Concumer Done"); } } }