在java中通过GUI停止正在运行的进程
我有一个执行TestNG自动化脚本的GUI程序。这意味着用户可以轻松地配置一些设置并启动他们想要的自动化脚本 我需要添加的一件事是能够立即停止正在运行的TestNG进程。类似于在Eclipse中,“终止”按钮将立即停止正在运行的任何东西 启动TestNG测试的代码如下所示:在java中通过GUI停止正在运行的进程,java,user-interface,testng,terminate,Java,User Interface,Testng,Terminate,我有一个执行TestNG自动化脚本的GUI程序。这意味着用户可以轻松地配置一些设置并启动他们想要的自动化脚本 我需要添加的一件事是能够立即停止正在运行的TestNG进程。类似于在Eclipse中,“终止”按钮将立即停止正在运行的任何东西 启动TestNG测试的代码如下所示: public class ScriptRunner implements Runnable { public void runScript() { Thread testRun = new Thre
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
}
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();
}
}
}
使用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();
}
});
}
}
公共类ProcessFactory{
私有静态集进程=新HashSet();
私有静态布尔值isRunning=true;
公共静态同步进程createProcess(…)引发{
如果(!正在运行)
扔。。。
…//创建生成的进程
流程。添加(流程);
返回过程;
}
公共静态同步的void killAll(){
isRunning=false;
用于(流程p:流程)
p、 破坏();
进程。清除();
}
公共静态无效注册表shutdownhook(){
Runtime.getRuntime().addShutdownHook(新线程(){
无效运行(){
基拉尔();
}
});
}
}
这可以通过添加一种机制来改进,该机制可以删除已经死掉的进程,但是您可以得到一般的想法。您可以使用ExecutorService在另一个线程中启动测试执行。通过选择所需的执行器服务,您可以选择让多个线程并行,也可以选择让一个线程按顺序执行所有测试 在此之后,通过对同一executor服务实例调用submit()方法,开始执行该实例中的所有测试。通过调用shutdownNow()方法,可以停止执行所有提交的可运行文件 使用同一个ExecutorService实例很重要,否则您将在不同的线程中启动每个测试,您将无法断开执行链(或通过对所有线程调用shutdownNow()。这是怎么回事, 添加一个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();
}
}
一条新的线怎么样?您必须添加一个
私有线程以及何时启动
thread = new thread(){
@Override
public void run(){
//start process here
}
};
thread.start();
停止“终止”
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();
}
我最近正在研究executor框架。这里我列出了我的问题
如果正在执行某些IO操作,请小心,executor服务可能不会立即关闭。如果您看到下面的代码stopThread
,这很重要,因为它告诉您的程序线程已被要求停止。你可以停止一些你正在做的迭代。
我将按如下方式修改您的代码:
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
}
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();
}
}
}
公共类MyClass{
私人遗嘱执行人服务;
私有布尔stopThread=false;
公开作废开始(){
//为线程命名
BasicThreadFactory=新的BasicThreadFactory.Builder()
.namingPattern(“线程-%d”).build();
executorService=Executors.newSingleThreadExecutor(工厂);
executorService.execute(新的Runnable(){
@凌驾
公开募捐{
试一试{
doTask();
}捕获(例外e){
错误(“索引失败”,e);
}
}
});
executorService.shutdown();
}
私有void doTask(){
info(“开始对我的对象重新编制索引”);
List listOfMyObjects=new MyClass().getMyObjects();
用于(myObject myObject:ListOfMyObject){
如果(stopThread){//这对于停止进一步的索引非常重要
返回;
}
DbObject dbObjects=getDataFromDB();
//做一些工作
}
}
公共停车场(){
this.stopThread=true;
if(executorService!=null){
试一试{
//等待1秒以关闭所有线程
执行器服务。等待终止(1,时间单位。秒);
}捕捉(中断异常e){
Thread.currentThread().interrupt();
}
}
}
}系统退出(0);将终止JVMinstantly@OluCode是的,但这不会也杀死我的GUI应用程序吗?我需要一种方法来杀死正在运行的TestNG对象。如果它是一个线程,请使用类似ExecutorService的线程管理器为您处理线程生命,并调用serviceObject.shutDownNow();为什么不将TestNG
线程保存在run()
方法范围之外,并从另一个方法终止它?@OluCode谢谢,但它似乎不起作用。关闭现在();仅停止TestNG对象正在执行的即时操作(例如,如果对象必须在单独的浏览器中分别运行10个测试,则调用shutDownNow()一次仅停止1个测试)