等待递归的Thread-Producer

时间:2014-03-18 22:04:29

标签: java multithreading recursion

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

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

以下是一些代码:

protected static List<Runnable> threads;
private static ExecutorService threadPool;

protected final synchronized void hookThread(Runnable thread) {
        if (threadPool == null) {
            threadPool = Executors.newFixedThreadPool(15);
            threads = new ArrayList<Runnable>();
        }
        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,但我不知道如何正确实现它。

问候凯文

1 个答案:

答案 0 :(得分:0)

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

import java.util.concurrent.*;
public class ThreadingExample {

    public static void main(String args[]){
        BlockingQueue<Message> blockingQueue = new ArrayBlockingQueue<Message>(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<Message> blockingQueue;
    Producer(BlockingQueue<Message> 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<Message> blockingQueue;
    Consumer(BlockingQueue<Message> 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");
        }
    }
}