Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在后台线程中运行无限循环并重新启动它_Java_Multithreading_Concurrency_Infinite Loop - Fatal编程技术网

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

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

我想创建一个具有无限while循环的线程,在启动该线程后,我的要求是重新启动该线程

我不知道怎么做

示例:

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();
}
}