我有一个执行TestNG自动化脚本的GUI程序。这意味着用户可以轻松配置一些设置并启动他们想要的自动化脚本。
我需要补充的一点是能够立即停止正在运行的TestNG流程。就像在Eclipse中一样,“终止”按钮会立即停止正在运行的任何内容。
这是启动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()
可能需要几分钟才能完成,它正在执行多项操作,打开/关闭浏览器窗口等。
如何立即终止流程,就像从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
}
答案 0 :(得分:3)
使用ProcessBuilder或Runtime生成子JVM进程,当用户请求脚本停止运行时,您将能够终止该进程。
答案 1 :(得分:2)
您可以使用ExecutorService将测试执行开始到另一个线程中。通过选择所需的执行服务,您可以选择在并行或juste一个线程中为所有测试顺序选择多个线程。
之后,通过调用submit()方法在同一个执行器服务实例中开始执行所有测试。您可以通过调用shutdownNow()方法停止执行所有提交的runnable。
使用相同的ExecutorService实例非常重要,否则您将在另一个线程中启动每个测试,并且您不会启用中断执行链(或通过在所有测试中调用shutdownNow())。
答案 2 :(得分:1)
保存所有已创建的进程,并在程序结束时将其终止:
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();
}
});
}
}
这可以通过添加一个删除已经死的进程的机制来改进,但是你可以得到一般的想法。
答案 3 :(得分:1)
这个怎么样, 添加一个volatile静态布尔值并使线程代码看起来像......
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();
}
}
答案 4 :(得分:1)
新线程怎么样?您必须在gui中添加private Thread thread;
,然后何时开始
thread = new thread(){
@Override
public void run(){
//start process here
}
};
thread.start();
并停止&#34;终止&#34;
thread.stop();
(已删除)或thread.setDeamon(true);
每次我必须停止使用gui的过程。
希望我能提供帮助;)
答案 5 :(得分:1)
在您的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();
}
答案 6 :(得分:1)
我最近在处理执行程序框架。我在这里列出了我的问题 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();
}
}
}
}