1

我似乎无法为我的问题找到一个好的答案:假设我有一定数量的可运行形式

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
    }
}

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

EG:我有 2 个带有无限循环的 Runnables(它们必须是无限的才能完成他们所做的任务)和一个 1 个线程的线程池(为简单起见)。我希望这两个循环交替使用线程。Runnables 彼此不认识。

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

感谢您的任何帮助或建议

编辑: Jost 解决方案解决了提供我所追求的可扩展性的问题。谢谢你。

4

5 回答 5

3

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

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()程序在完成之前不会开始(听起来有点奇怪 - 但在池中有多个线程的情况下才有意义)。

*约斯特

于 2013-07-16T11:27:39.953 回答
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();
于 2013-07-16T11:07:06.377 回答
0

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

通常,当在独立线程中运行独立的可运行文件时,操作系统调度已经负责交替它们。由于它们永无止境,请确保将循环包装在 try/catch(InterruptedException) 块中,以便能够很好地终止线程。

于 2013-07-16T11:26:11.433 回答
0

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

于 2013-07-16T14:56:03.967 回答
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();
    }
}
}
于 2013-07-16T11:09:57.547 回答