在 java 中通过 GUI 停止 运行 进程
Stopping a running process via GUI, in java
我有一个执行 TestNG 自动化脚本的 GUI 程序。这意味着用户可以轻松配置一些设置并启动他们想要的自动化脚本。
我需要添加的一件事是立即停止 运行 TestNG 进程的能力。就像在 Eclipse 中一样,'Terminate' 按钮将立即停止任何 运行.
启动 TestNG 测试的代码如下所示:
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();
}
}
根据评论,tng.run()
可能需要几分钟才能完成,它正在执行几件事,opening/closing 浏览器 windows,等等
我怎样才能立即终止进程,就像 运行 来自 IDE 的应用程序一样?
编辑:
根据评论,我正在尝试使用 ServiceExecutor 并且 shutDownNow()
代码如下所示:
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
}
使用 ProcessBuilder 或 Runtime 生成子 JVM 进程,当用户请求脚本停止时,您将能够终止该进程 运行。
保存所有创建的进程并在程序结束时终止它们:
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();
}
});
}
}
这可以通过添加一种机制来改进,该机制可以删除已经死掉的进程,但您已经了解了总体思路。
您可以使用 ExecutorService 开始测试执行到另一个线程。通过选择您需要的执行程序服务,您可以选择并行使用多个线程,也可以按顺序为所有测试设置一个线程。
之后,通过调用 submit() 方法在同一执行器服务实例中开始执行所有测试。您可以通过调用 shutdownNow() 方法停止所有提交的可运行程序的执行。
使用相同的 ExecutorService 实例很重要,否则您将在不同的线程中启动每个测试,并且您将无法中断执行链(或通过对所有这些实例调用 shutdownNow())。
这个呢,
添加一个 volatile static boolean 并使线程代码看起来像...
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
}
现在您可以在主 GUI 中添加一个按钮,该按钮只需将 runThread
设置为 false,这样线程将几乎立即终止,而在您按下 Stop
按钮时保留所有剩余代码。
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();
}
}
新线程怎么样?你必须在 gui 中添加一个 private Thread thread;
并且你什么时候开始
thread = new thread(){
@Override
public void run(){
//start process here
}
};
thread.start();
并停止"terminate"
thread.stop();
(堕落)或thread.setDeamon(true);
每次我必须通过 gui 停止进程时,我都会使用它。
希望我能帮到你 ;)
在你的 GUI 某处你有类似的东西
ScriptRunner scriptRunner = new ScriptRunner();
scriptRunner.runScript();
想停止时调用
scriptRunner.interrupt();
更改ScriptRunner中的代码
private Thread testRun;
public void runScript() {
testRun = new Thread(this);
testRun.start();
}
public void interrupt() {
testRun.interrupt();
}
我最近在研究执行器框架。在这里我列出了我的问题
http://programtalk.com/java/executorservice-not-shutting-down/
如果您正在执行某些 IO 操作,请注意执行程序服务可能不会立即关闭。如果你看到下面的代码 stopThread
很重要,因为它告诉你的程序线程已被要求停止。你可以停止你正在做的一些迭代。
我将这样修改您的代码:
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();
}
}
}
}
我有一个执行 TestNG 自动化脚本的 GUI 程序。这意味着用户可以轻松配置一些设置并启动他们想要的自动化脚本。
我需要添加的一件事是立即停止 运行 TestNG 进程的能力。就像在 Eclipse 中一样,'Terminate' 按钮将立即停止任何 运行.
启动 TestNG 测试的代码如下所示:
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();
}
}
根据评论,tng.run()
可能需要几分钟才能完成,它正在执行几件事,opening/closing 浏览器 windows,等等
我怎样才能立即终止进程,就像 运行 来自 IDE 的应用程序一样?
编辑:
根据评论,我正在尝试使用 ServiceExecutor 并且 shutDownNow()
代码如下所示:
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
}
使用 ProcessBuilder 或 Runtime 生成子 JVM 进程,当用户请求脚本停止时,您将能够终止该进程 运行。
保存所有创建的进程并在程序结束时终止它们:
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();
}
});
}
}
这可以通过添加一种机制来改进,该机制可以删除已经死掉的进程,但您已经了解了总体思路。
您可以使用 ExecutorService 开始测试执行到另一个线程。通过选择您需要的执行程序服务,您可以选择并行使用多个线程,也可以按顺序为所有测试设置一个线程。
之后,通过调用 submit() 方法在同一执行器服务实例中开始执行所有测试。您可以通过调用 shutdownNow() 方法停止所有提交的可运行程序的执行。
使用相同的 ExecutorService 实例很重要,否则您将在不同的线程中启动每个测试,并且您将无法中断执行链(或通过对所有这些实例调用 shutdownNow())。
这个呢, 添加一个 volatile static boolean 并使线程代码看起来像...
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
}
现在您可以在主 GUI 中添加一个按钮,该按钮只需将 runThread
设置为 false,这样线程将几乎立即终止,而在您按下 Stop
按钮时保留所有剩余代码。
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();
}
}
新线程怎么样?你必须在 gui 中添加一个 private Thread thread;
并且你什么时候开始
thread = new thread(){
@Override
public void run(){
//start process here
}
};
thread.start();
并停止"terminate"
thread.stop();
(堕落)或thread.setDeamon(true);
每次我必须通过 gui 停止进程时,我都会使用它。
希望我能帮到你 ;)
在你的 GUI 某处你有类似的东西
ScriptRunner scriptRunner = new ScriptRunner();
scriptRunner.runScript();
想停止时调用
scriptRunner.interrupt();
更改ScriptRunner中的代码
private Thread testRun;
public void runScript() {
testRun = new Thread(this);
testRun.start();
}
public void interrupt() {
testRun.interrupt();
}
我最近在研究执行器框架。在这里我列出了我的问题 http://programtalk.com/java/executorservice-not-shutting-down/
如果您正在执行某些 IO 操作,请注意执行程序服务可能不会立即关闭。如果你看到下面的代码 stopThread
很重要,因为它告诉你的程序线程已被要求停止。你可以停止你正在做的一些迭代。
我将这样修改您的代码:
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();
}
}
}
}