2

I want to create a thread with the infinite while loop and after sometime starting that thread my requirement is to restart the thread.

I don't know how to do that.

Example:

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

if(condition)
   th.restart();
Clijsters
  • 4,031
  • 1
  • 27
  • 37
Shubham Naphade
  • 49
  • 3
  • 10
  • 3
    Why do you need to restart it, if it's infinite? Plus, Java thread can't be restarted once it stopped. – Victor Sorokin Jan 09 '18 at 09:49
  • @VictorSorokin this thread is going to calculate values that is dependent upon some other value x and if x gets change the whole loop should be restarted from the begining. – Shubham Naphade Jan 09 '18 at 09:53
  • Such things can be done in different ways, depending on context. Elaborate your question with details, for now it's too vague to give helpful answer. – Victor Sorokin Jan 09 '18 at 09:55
  • 2
    Actually, it looks like you need something like `BlockingQueue q` which being fed with values of `x` and your calculating thread should call `q.poll(timeout)` and then proceed with calculation, checking once in a while if there's new value(s) in the queue: `if (!q.isEmpty()) restart()`. – Victor Sorokin Jan 09 '18 at 09:59

5 Answers5

1

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

It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.

I don't know why you are trying to do this but if you want a workaround you can just interrupt the current thread running and start a new instance.

Karl Alexander
  • 351
  • 4
  • 16
0

Why not create your own thread class (or implementing runnable) and add some property to it that controls the execution. For example something like:

public class MyThread implements Runnable {

private  MyThreadState state;
public changeState(MyThreadState state){

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

}

You can substitute state with values that you check for and stuff like that. Basically creating a class for the thread gives you much more flexibility than creating it with an anonymous run function like in your example.

After that you can create the thread like:

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

The basic idea is that you probably don't need to restart the thread (restart the current instance). You can use that thread you already have running and restart the calculation it is doing.

Veselin Davidov
  • 7,031
  • 1
  • 15
  • 23
  • but then I've to return multiple values from the thread, how to do that? – Shubham Naphade Jan 09 '18 at 09:58
  • In the same manner - the thread can have a getter for the result. Or if you want to wait for the thread to give a result you can create it with a callback and use that callback when the result is ready – Veselin Davidov Jan 09 '18 at 10:14
  • For example something like: private MyResultListener listener; listener.sendNewResult("result!"); Thread th=new MyThread( myListener); like a normal java class ;) – Veselin Davidov Jan 09 '18 at 10:14
0

From java docs: It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.

S-Wing
  • 485
  • 6
  • 25
0

As Karl Alexander said, it's bad to restart a thread. Instead you may do it like Veselin Davidov said and create your own thread-class. If you wish to "restart" the thread you may instead simply let your old thread start a new identical thread before completing its execution. To return values from your thread you may use a ConcurrentLinkedQueue with Objects containing all values you wish to return.

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

You may then create, get results and restart like this

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

Note that the restart currently may have more than one thread running at the same time since restart does not wait for the old thread to finish before calling newThread(). If this is a problem you need to make the code synchronized instead.

Jotunacorn
  • 496
  • 1
  • 4
  • 12
0

A thread cannot be restarted during its life cycle so you can only create a new Thread instance.

Look at the following example, you should create your own thread class and define a flag for the control expire time of the loop.

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