【问题标题】:Wait for recursive Thread-Producer等待递归线程生产者
【发布时间】:2014-04-24 21:06:48
【问题描述】:

我有一个收集器,用于搜索游戏中的动作。我在递归搜索中搜索,以获取游戏中所有可能的动作。

出于性能原因,我使用了一个线程池,并且每个找到的动作都会向池中添加一个新线程,以可能扩展旧动作。

这里有一些代码:

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();

}

这是父类的sn-p。现在孩子来了,它正在寻找动作。

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,但我不知道如何正确实现它。

问候凯文

【问题讨论】:

  • 您使用的是AtomicInteger 还是普通的int?后者不起作用,但第一个应该(使用方法incrementAndGetdecrementAndGet)。
  • ArrayList 线程安全吗?

标签: java multithreading recursion


【解决方案1】:

以下程序使用 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");
        }
    }
}

【讨论】:

    猜你喜欢
    • 2021-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2018-09-13
    相关资源
    最近更新 更多