我想创建一个带有无限while循环的线程,并且在某个时候启动该线程之后,我的要求是重新启动线程。
我不知道该怎么做。
示例:
Thread th = new Thread(() -> {
while(true)
{
//some operation
}
});
th.start();
if(condition)
th.restart();
答案 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....