Stop running process via GUI in java

I have a GUI program that runs TestNG automation scripts. This meant that users could easily configure some parameters and run the automatic script they want.

One thing I need to add is the ability to instantly stop the running TestNG process. Something like the β€œFinish” button in Eclipse will immediately stop everything that works.

This is what the code that runs the TestNG tests looks like this:

public class ScriptRunner implements Runnable { public void runScript() { Thread testRun = new Thread(this); testRun.start(); } @Override public void run() { //various other things are configured for this, //but they're not relevant so I left them out TestNG tng = new TestNG(); //While this runs, various browser windows are open, //and it could take several minutes for it all to finish tng.run(); } } 

According to the comment, tng.run() may take several minutes, and it performs several actions, opening / closing browser windows, etc.

How can I just terminate the process immediately, for example, when starting an application from the IDE?

EDIT:

In the comments, I am trying to use shutDownNow() and shutDownNow() . The code is as follows:

 ExecutorService executorService = Executors.newFixedThreadPool(10); public void runScript() { executorService.execute(this); } //this method gets called when I click the "stop" button public void stopRun() { executorService.shutdownNow(); } @Override public void run() { //same stuff as from earlier code } 
+6
source share
7 answers

Recently, I worked on an artist map. Here I listed my problem http://programtalk.com/java/executorservice-not-shutting-down/

Be careful if you perform some I / O; the executing service may not shut down immediately. If you see that the stopThread code stopThread important because it tells your program that the thread was requested to stop. And you can stop some iteration of what you are doing. I will modify your code as follows:

 public class MyClass { private ExecutorService executorService; private boolean stopThread = false; public void start() { // gives name to threads BasicThreadFactory factory = new BasicThreadFactory.Builder() .namingPattern("thread-%d").build(); executorService = Executors.newSingleThreadExecutor(factory); executorService.execute(new Runnable() { @Override public void run() { try { doTask(); } catch (Exception e) { logger.error("indexing failed", e); } } }); executorService.shutdown(); } private void doTask() { logger.info("start reindexing of my objects"); List<MyObjects> listOfMyObjects = new MyClass().getMyObjects(); for (MyObjects myObject : listOfMyObjects) { if(stopThread){ // this is important to stop further indexing return; } DbObject dbObjects = getDataFromDB(); // do some task } } public void stop() { this.stopThread = true; if(executorService != null){ try { // wait 1 second for closing all threads executorService.awaitTermination(1, TimeUnit.SECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } 

}

+1
source

Create a child JVM process using ProcessBuilder or Runtime, and you can end this process when the user asks for the script to stop working.

+3
source

You can use ExecutorService to run test execution on another thread. You can choose to have many threads in parrallel or juste one thread for all tests sequentially, choosing which artist service you need.

After that, run all the tests in one instance of the executing service by calling the submit () method. You can stop the execution of all runnables provided by calling the shutdownNow () method.

It is important to use the same instance of ExecutorService, otherwise you start each test in a different thread and you cannot break the execution chain (or by calling shutdownNow () for all of them).

+2
source

Save all created processes and kill them when your program ends:

 public class ProcessFactory { private static Set<Process> processes = new HashSet<>(); private static boolean isRunning = true; public static synchronized Process createProcess(...) throws ... { if (!isRunning) throw ... ... // create your spawned process processes.add(process); return process; } public static synchronized void killAll() { isRunning = false; for (Process p : processes) p.destroy(); processes.clear(); } public static void registerShutdownHook() { Runtime.getRuntime().addShutdownHook(new Thread() { void run() { killAll(); } }); } } 

This can be improved by adding a mechanism that removes already dead processes, but you get a general idea.

+1
source

How about this, add volatile static boolean and make the stream code look like ...

 if(ScriptRunner.runThread){ //Do some stuff here } if(ScriptRunner.runThread){ //Do some other stuff here } if(ScriptRunner.runThread){ //Do some other stuff here } if(ScriptRunner.runThread){ //Do rest of the stuff here } 

Now you can add a button to your main GUI, which simply sets the runThread parameter to false so that the thread terminates almost instantly, leaving all remaining code unaffected when you click the Stop button.

 public class ScriptRunner implements Runnable { volatile static Boolean runThread = true; public void runScript() { Thread testRun = new Thread(this); testRun.start(); } public void terminate(){ runThread = false; } @Override public void run() { //various other things are configured for this, //but they're not relevant so I left them out TestNG tng = new TestNG(); //While this runs, various browser windows are open, //and it could take several minutes for it all to finish tng.run(); } } 
+1
source

How about a new topic? You must add private Thread thread; in gui and when you run

 thread = new thread(){ @Override public void run(){ //start process here } }; thread.start(); 

and stop the "completion"

thread.stop(); (pulled back) or thread.setDeamon(true);

Every time I have to stop a process using gui, I use this.

Hope I can help;)

+1
source

Somewhere in your GUI is something like

 ScriptRunner scriptRunner = new ScriptRunner(); scriptRunner.runScript(); 

If you want to stop the call,

 scriptRunner.interrupt(); 

Change the code in ScriptRunner

 private Thread testRun; public void runScript() { testRun = new Thread(this); testRun.start(); } public void interrupt() { testRun.interrupt(); } 
+1
source

All Articles