How to Start/Stop/Restart a Thread in Java

How to start/stop/restart a thread in Java?

Once a thread stops you cannot restart it. However, there is nothing stopping you from creating and starting a new thread.

Option 1: Create a new thread rather than trying to restart.

Option 2: Instead of letting the thread stop, have it wait and then when it receives notification you can allow it to do work again. This way the thread never stops and will never need to be restarted.

Edit based on comment:

To "kill" the thread you can do something like the following.

yourThread.setIsTerminating(true); // tell the thread to stop
yourThread.join(); // wait for the thread to stop

Stop and restart a already running thread

Java threads are not restartable. For what you are trying to achieve, you could create a new thread each time, or you could look at an ExecutorService. Just create a single threaded executor (Executors.newSingleThreadExecutor), and submit your runnable to it every time you need it to run.

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(runnable);

How can a dead thread be restarted?

Thread lifecycle image

If you look at the Thread Life Cycle Image, there is no way you can go back to new position once your thread has terminated.

So there is no way to bring back the dead thread to runnable state,instead you should create a new Thread instance.

how to restart a thread

Instead of explaining, I just coded up a skeleton example. I did not test it terribly well, but it may be of some use.

In order to monitor a(nother) file, just create a new Monitor, passing it a ScheduledExecutorService. Starting and stopping monitoring is straightforward. You can (should) reuse the same executor for multiple monitors.

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public interface Event
{
}

public interface Listener
{
void handle(Event event);
}

public class Monitor
{
private static final int CHECK_EVERY_SECONDS = 10;
private static final int RECHECK_AFTER_IF_NOT_EXISTS_SECONDS = 30;

private File file;
private ScheduledExecutorService executor;
private boolean active;
private List<Listener> listeners;

public Monitor(File file, ScheduledExecutorService executor)
{
super();
this.file = file;
this.executor = executor;
listeners = new ArrayList<Listener>();
}

public synchronized void start()
{
if (active)
{
return;
}
active = true;
executor.execute(new Runnable()
{
public void run()
{
synchronized (Monitor.this)
{
if (!active)
{
System.out.println("not active");
return;
}
}
if (!file.exists())
{
System.out.println("does not exist, rescheduled");
executor.schedule(this, RECHECK_AFTER_IF_NOT_EXISTS_SECONDS, TimeUnit.SECONDS);
return;
}
Event event = doStuff(file);
System.out.println("generated " + event);
updateListeners(event);
System.out.println("updated listeners and rescheduled");
executor.schedule(this, CHECK_EVERY_SECONDS, TimeUnit.SECONDS);
}
});
}

private Event doStuff(final File file)
{
return new Event()
{
public String toString()
{
return "event for " + file;
}
};
}

public synchronized void stop()
{
active = false;
}

public void addListener(Listener listener)
{
synchronized (listeners)
{
listeners.add(listener);
}
}

public void removeListener(Listener listener)
{
synchronized (listeners)
{
listeners.remove(listener);
}
}

private void updateListeners(Event event)
{
synchronized (listeners)
{
for (Listener listener : listeners)
{
listener.handle(event);
}
}
}

public static void main(String[] args) throws IOException
{
ScheduledExecutorService executor = Executors.newScheduledThreadPool(4);
File file = new File("test.png");
Monitor monitor = new Monitor(file, executor);
monitor.addListener(new Listener()
{
public void handle(Event event)
{
System.out.println("handling " + event);
}
});
monitor.start();
System.out.println("started...");
System.in.read();
monitor.stop();
System.out.println("done");
executor.shutdown();
}

}

How to stop and start a Thread with new configuration?

A thread can't actually be "restarted" once the run method has finished executing. You have two options basically:

  1. Introduce a loop that causes the thread to be suspended (e.g. call a wait) when a condition is met. That way you can "pause" the thread, change the hostname and then signal it to resume.
  2. Cause the thread to finish its code, discard it and then start a new thread with the same Runnable object.

Edit: So what you can do in the restart method is to call to close method on the dt object. This will close the sockets and cause an IOException that will make the thread exit its run method. After that you can just start a new thread:

dt = new DataTransmitter(hostName,epnId);
new Thread(dt).start();

Java FX How to 'Stop' Thread Midway and Restart it or destroy it

I found Solution to my problem. Now my question is there any better way to achieve the same result
Because I'm getting and yellow warring which means I'm doing it the wrong way

Sample Image

Luncher.java

    package project;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Luncher extends Application
{

@Override
public void start(Stage primaryStage) {
try {

Parent root = FXMLLoader.load(getClass().getResource("Window.fxml"));

Scene scene = new Scene(root);

primaryStage.setScene(scene);
primaryStage.show();

} catch(Exception e) {
System.err.println("Luncher Failed !" +e);
}
}

public static void main(String[] args)
{

launch(args);

}

}

Controller.java

package project;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.FlowPane;

public class Controller implements Initializable
{

@FXML
public FlowPane flowPane;

//A class that implements Runable, So i can start a thead there
private MyRunableClass my_run_class;
private Thread t; //Thread object

@Override
public void initialize(URL location, ResourceBundle resources)
{
new ListOfNames(); //Init list of names and creating Array list, In real program i will get this list from database
my_run_class = new MyRunableClass(this);

}

@FXML
void clear_Button(ActionEvent event)
{
flowPane.getChildren().clear();
}

@FXML
void start_Button(ActionEvent event)
{
t = new Thread(my_run_class);
t.start();
}

@FXML
void stop_Button(ActionEvent event) {
t.suspend(); ///NOT WORKING???????? any way to stop running thread
}

private boolean firstTime_thread_running = true; // To check Whether i clicked '1st' time or 'second' time

@FXML
void refresh_Button(ActionEvent event)
{

if(firstTime_thread_running == false){

//Stop
// my_run_class.stop = true; //Exist loop
t.suspend();
System.out.println("Suspend");

} else
{
firstTime_thread_running = false;
}

//Clean
flowPane.getChildren().clear(); // cleaning screen
System.out.println("Screen clear");

//Restart , well.. at least that what i want
t = new Thread(my_run_class);
t.setDaemon(true);
t.start(); //Start Thread
System.out.println("Stoped Thread Started again");

}

}

MyRunableClass.java

    package project;

import javafx.application.Platform;
import javafx.scene.control.Button;

public class MyRunableClass implements Runnable
{
private Controller controller;

public MyRunableClass(Controller controller)
{
//Getting FXML Controller
this.controller = controller;
}

// public boolean stop = false;

@Override
public void run()
{

for (String name : ListOfNames.getlist())
{
// if(stop) // Exit for loop if true
// {
// break;
// }
Platform.runLater(new Runnable()
{

@Override
public void run()
{

Button btn = new Button("Button : "+name);

System.out.println(name);

controller.flowPane.getChildren().add(btn);
}
});

try {
Thread.sleep(1); // Wait for half sec this time
} catch (InterruptedException e) { // try catch it needed for some reason
e.printStackTrace();
}

}

}

}

ListOfNames.java

    package project;

import java.util.ArrayList;

public class ListOfNames
{
private static ArrayList<String> list_of_names ;

public ListOfNames()
{
list_of_names = new ArrayList<>();
list_of_names.add("A");
list_of_names.add("B");
list_of_names.add("C");
list_of_names.add("D");
list_of_names.add("E");
list_of_names.add("F");
list_of_names.add("G");
list_of_names.add("H");
list_of_names.add("I");
list_of_names.add("J");
list_of_names.add("K");
list_of_names.add("L");
list_of_names.add("M");
list_of_names.add("N");
list_of_names.add("O");
list_of_names.add("P");
list_of_names.add("Q");
list_of_names.add("R");
list_of_names.add("S");
list_of_names.add("T");
list_of_names.add("U");
list_of_names.add("V");
list_of_names.add("W");
list_of_names.add("X");
list_of_names.add("Y");
list_of_names.add("Z");

}

public static ArrayList<String> getlist() {
return list_of_names;
}
}

Window.fxml

    <?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.FlowPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="413.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="project.Controller">
<children>
<FlowPane fx:id="flowPane" layoutX="2.0" layoutY="61.0" prefHeight="352.0" prefWidth="600.0" style="-fx-border-color: #000000; -fx-border-insets: 1.1; -fx-border-width: 5;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="61.0" />
<Button layoutX="405.0" layoutY="14.0" mnemonicParsing="false" onAction="#stop_Button" prefHeight="39.0" prefWidth="80.0" text="Stop" />
<Button layoutX="313.0" layoutY="14.0" mnemonicParsing="false" onAction="#start_Button" prefHeight="39.0" prefWidth="80.0" text="Star" />
<Button layoutX="497.0" layoutY="14.0" mnemonicParsing="false" onAction="#clear_Button" prefHeight="39.0" prefWidth="80.0" text="Clean" />
<Button layoutX="40.0" layoutY="14.0" mnemonicParsing="false" onAction="#refresh_Button" prefHeight="39.0" prefWidth="109.0" text="Refresh" />
</children>
</AnchorPane>


Related Topics



Leave a reply



Submit