多线程 - 在Threadpool中安排无休止的runnables

时间:2013-07-16 10:58:29

标签: java multithreading threadpool runnable

我似乎无法找到解决问题的好方法: 假设我有一定数量的

形式的runnables
public class NeverendingRunner implements Runnable {

//...

@Override
public void run() {
    while(true){
        //Do what you have to do

        //At the end of the iteration, get back in queue
    }
}

如果我使用线程池来运行它们,显然它们永远不会离开执行。 我想在迭代结束时的评论中安排它们。

E.G。:我有2个具有无限循环的Runnables(他们必须为他们所做的任务无限)和1个线程的踏板(为简单起见)。我希望这两个循环交替使用线程。 Runnables彼此不认识。

我不知道是否可以做到这一点。

感谢您提供任何帮助或建议

编辑:Jost解决方案解决了提供我的目标可扩展性的问题。谢谢。

5 个答案:

答案 0 :(得分:3)

我认为您应该使用ThreadPoolExecutor,删除无限循环并启用两个Runnables将自己重新安排到执行程序。此代码段可能有所帮助:

public class Task implements Runnable
{
    private ReentrantLock lock;
    private ExecutorService executor;

    public Task(ExecutorService executor)
    {
        this.executor=executor;
    }

    @Override
    public void run()
    {

        //do some stuff
        //...

        lock.lock();
        executor.execute(this);
        lock.unlock();
    }
}

注意:我没有尝试过这个例子 - 但总的来说它应该可行。锁确保执行程序在完成之前不会以run()开头(听起来有点奇怪 - 但在池中有多个线程的情况下有意义。)

*斯特

答案 1 :(得分:1)

我可以想象这样的事情

    final Runnable task1 = new Runnable() {
        public void run() {
            for(int i = 0; i < 10; i++) {
                System.out.println("task1");
            }
        }
    };
    final Runnable task2 = new Runnable() {
        public void run() {
            for(int i = 0; i < 10; i++) {
                System.out.println("task2");
            }
        }
    };
    new Thread() {
        public void run() {
            for(;;) {
                task1.run();
                task2.run();
            }
        };
    }.start();

答案 2 :(得分:0)

以下代码可能会达到此目的,但这不是最佳实现

CyclicBarrier run1 = new CyclicBarrier(2);
CyclicBarrier run2 = new CyclicBarrier(2);

public class RUN1 implements Runnable {

@Override
public void run() {
    while(true){
        //Do what you have to do
        //At the end of the iteration, get back in queue
         run1.await();
         run2.await();
    }
}
}

public class RUN2 implements Runnable {

@Override
public void run() {
    while(true){
         run1.await();
        //Do what you have to do
        //At the end of the iteration, get back in queue
         run2.await();
    }
}
}

答案 3 :(得分:0)

如果runnables彼此不相关,则它们可能不必由同一个线程运行。在任何情况下,通常更好地考虑runnables及其可能的依赖关系而不是线程。如果有一个真正的原因让他们交替运行(甚至可能在定义的切换点交替,那么也许他们(或者他们内部发生的事情)应该彼此知道。

通常,在独立线程中运行独立的runnable时,OS调度会负责交替它们。因为它们是无穷无尽的,所以请确保将循环包装在try / catch(InterruptedException)块中,以便能够很好地杀死线程。

答案 4 :(得分:0)

请参阅文件DataflowVariable中的方法loopAct()。这是你的情况的开销,但想法很简单:保持一个布尔变量显示任务是否正常;当任务完成所有工作时,它会关闭变量并退出;当另一个线程向任务提供作业,并且变量显示它不起作用时,它会打开变量并将任务发送给执行程序。这样,您永远不会同时执行多个线程执行的任务。