Java 如何在后台线程中运行无限循环并重新启动它
我想创建一个具有无限while循环的线程,在启动该线程后,我的要求是重新启动该线程 我不知道怎么做 示例:Java 如何在后台线程中运行无限循环并重新启动它,java,multithreading,concurrency,infinite-loop,Java,Multithreading,Concurrency,Infinite Loop,我想创建一个具有无限while循环的线程,在启动该线程后,我的要求是重新启动该线程 我不知道怎么做 示例: Thread th = new Thread(() -> { while(true) { //some operation } }); th.start(); if(condition) th.restart(); 为什么不创建自己的线程类(或实现runnable)并向其中添加一些控制执行的属性呢。例如: public class
Thread th = new Thread(() -> {
while(true)
{
//some operation
}
});
th.start();
if(condition)
th.restart();
为什么不创建自己的线程类(或实现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
基本思想是您可能不需要重新启动线程(重新启动当前实例)。您可以使用已经运行的线程并重新启动它正在进行的计算 见
多次启动线程是不合法的。特别是,线程一旦完成执行,就不能重新启动
我不知道你为什么要这样做,但是如果你想解决这个问题,你可以中断当前线程的运行并启动一个新实例。来自java文档:
多次启动线程是不合法的。特别是,一个线程一旦完成执行就不能重新启动。正如Karl Alexander所说,重新启动线程是不好的。相反,您可以像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;
}
}
请注意,重新启动当前可能有多个线程同时运行,因为重新启动不会在调用
newThread()
之前等待旧线程完成。如果这是一个问题,您需要使代码同步。线程在其生命周期内无法重新启动,因此您只能创建一个新的线程实例
看看下面的示例,您应该创建自己的线程类,并为循环的控件过期时间定义一个标志
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();
}
}
------------结果----------------
杰克:我还活着,做点什么。。。。
杰克:我还活着,做点什么。。。。
杰克:我还活着,做点什么。。。。
杰克:我还活着,做点什么。。。。
杰克:我还活着,做点什么。。。。
杰克:我还活着,做点什么。。。。
玛丽:我还活着,做点什么。。。。
玛丽:我还活着,做点什么。。。。
杰克:我还活着,做点什么。。。。
杰克:我死了,做点什么。。。。
玛丽:我死了,做点什么。。。。
如果无限大,为什么需要重新启动它?另外,Java线程一旦停止就不能重新启动。@VictorSorokin此线程将计算依赖于其他值x的值,如果x发生更改,则整个循环应从一开始就应重新启动。根据上下文的不同,可以采用不同的方式来完成这些操作。详细阐述你的问题,因为现在它太模糊了,无法给出有用的答案。实际上,看起来你需要类似于BlockingQueue q
的东西,它被输入x
的值,你的计算线程应该调用q.poll(timeout)
,然后继续计算,偶尔检查一下队列中是否有新值:if(!q.isEmpty())restart()
。但是我必须从线程返回多个值,如何执行?以同样的方式-线程可以有一个结果的getter。或者,如果您想等待线程给出结果,您可以使用回调创建它,并在结果就绪时使用该回调,例如:private MyResultListener listener;sendNewResult(“result!”);Thread th=新的MyThread(myListener);与普通java类类似;)
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();
}
}