如何在后台线程中运行无限循环并重新启动它

时间:2018-01-09 09:45:24

标签: java multithreading concurrency infinite-loop

我想创建一个带有无限while循环的线程,并且在某个时候启动该线程之后,我的要求是重新启动线程。

我不知道该怎么做。

示例:

Thread th = new Thread(() -> {
    while(true)
    {
          //some operation
    }
});
th.start();

if(condition)
   th.restart();

5 个答案:

答案 0 :(得分:1)

请参阅https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#start%28%29

  

不止一次启动线程永远不合法。特别是,一旦完成执行,线程可能无法重新启动。

我不知道你为什么要这样做,但如果你想要一个解决方法,你可以中断当前运行的线程并启动一个新实例。

答案 1 :(得分:0)

为什么不创建自己的线程类(或实现runnable)并为其添加一些控制执行的属性。例如:

public class MyThread implements Runnable {

private  MyThreadState state;
public changeState(MyThreadState state){

}
@Override
public void run() {
  while(true){
       if(state = something) do something
  }

}

您可以使用您检查的值替换州和类似的东西。基本上为线程创建一个类比使用匿名运行函数创建一个类更灵活,就像在你的例子中一样。

之后你可以创建如下的线程:

Thread th=new MyThread();
th.start();
th.changeState(STATE_RESTART); //or whatever - that's just to get the idea

基本思想是你可能不需要重启线程(重启当前实例)。您可以使用已经运行的线程并重新开始计算。

答案 2 :(得分:0)

来自java docs: 不止一次启动线程永远不合法。特别是,一旦完成执行,线程可能无法重新启动。

答案 3 :(得分:0)

正如卡尔亚历山大所说,重启线程是不好的。相反,你可以像Veselin Davidov那样说并创建自己的线程类。如果你想“重新启动”线程,你可以简单地让你的旧线程在完成执行之前启动一个新的相同线程。要从线程返回值,您可以使用ConcurrentLinkedQueue,其中包含要返回的所有值的对象。

public class ThreadHolder{
    private Runnable thread;
    private ConcurrentLinkedQueue<Object> results = new ConcurrentLinkedQueue<>();

    public ThreadHolder() {
        thread = newThread();
    }

    public void restart() {
        thread.quit = true; //Quit old thread
        thread = newThread(); //Start a new one
    }

    public Object getResult() {
        return results.poll();
    }

    private Runnable newThread() {
        Runnable newThread = new Runnable() {
            boolean quit = false;
            @Override
            public void run() {
                while(true) {
                    //Do stuff
                    Object result = new ResultFromCalculation();
                    results.add(result)
                    if(quit) {
                        break;
                    }
                }
            }
        };
        newThread.start();
        return newThread;
    }
}

然后您可以创建,获取结果并像这样重新启动

ThreadHolder th = new ThreadHolder();
th.getResult(); //Null if no results have been created yet
th.restart();

请注意,重启当前可能同时运行多个线程,因为重新启动不会等待旧线程完成,然后再调用newThread()。如果这是一个问题,则需要使代码同步。

答案 4 :(得分:0)

线程无法在其生命周期中重新启动,因此您只能创建一个新的Thread实例。

请看下面的示例,您应该创建自己的线程类,并为循环的控制过期时间定义一个标志。

public class InfiniteLoopThread implements Runnable {

private boolean flag = true;


public void surrender() {
    this.flag = false;
}

@Override
public void run() {
    String name = Thread.currentThread().getName();
    while (true) {
        if (!this.flag) {
            System.out.println(name + ": I am dead, do something....");
            break;
        }
        System.out.println(name + ": I am alive, do something....");
    }
}

public static void main(String[] args) throws InterruptedException {
    InfiniteLoopThread jack = new InfiniteLoopThread();
    InfiniteLoopThread mary = new InfiniteLoopThread();
    Thread t1 = new Thread(jack);
    Thread t2 = new Thread(mary);
    t1.setName("Jack");
    t2.setName("Mary");
    t1.start();
    t2.start();
    Thread.sleep(500);
    jack.surrender();
    mary.surrender();
}
}

------------Outcome---------------- Jack: I am alive, do something.... Jack: I am alive, do something.... Jack: I am alive, do something.... Jack: I am alive, do something.... Jack: I am alive, do something.... Jack: I am alive, do something.... Mary: I am alive, do something.... Mary: I am alive, do something.... Jack: I am alive, do something.... Jack: I am dead, do something.... Mary: I am dead, do something....