我有一个收集者,在游戏中搜索动作。我在一个递归搜索中搜索,以便从游戏中获得所有可能的移动。
出于性能原因,我使用了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,但我不知道如何正确实现它。
问候凯文
答案 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");
}
}
}