Java-无法从主类停止runnable
我的头撞在桌子上,朋友们。这就是我想要实现的。我有一个主类,它将创建一个新线程。现在,当线程完成工作时,它将执行一些小的清理,线程将停止。然而,我在UI上有一个“停止”按钮,当按下该按钮时,应该“进行一些清理,然后杀死线程。问题是,我似乎无法更新我创建的新线程中的任何内容 以下是一些片段: 主类Java-无法从主类停止runnable,java,multithreading,runnable,Java,Multithreading,Runnable,我的头撞在桌子上,朋友们。这就是我想要实现的。我有一个主类,它将创建一个新线程。现在,当线程完成工作时,它将执行一些小的清理,线程将停止。然而,我在UI上有一个“停止”按钮,当按下该按钮时,应该“进行一些清理,然后杀死线程。问题是,我似乎无法更新我创建的新线程中的任何内容 以下是一些片段: 主类 runner = new Thread(new Controller1(options)); runner.start(); 在上面的代码中,我调用了我的Controller1类,并在构造函数中设置了
runner = new Thread(new Controller1(options));
runner.start();
在上面的代码中,我调用了我的Controller1类,并在构造函数中设置了一些“选项”。到目前为止,这一切都很正常
现在,在Controller1类中,这是我所拥有的
public volatile static boolean stopped;
public void run() {
while(!stopped ){
System.out.println("In run");
startProxy(proxyPort);
startWebDriver();
driver.get(http);
UIMainJSwing1.updateStartButton();
stopped=true;
}
//Run killAll to stop webdriver and the proxy
killAll();
System.out.println("Thread complete");
}
问题是,在主类中,我无法调用或将“stopped”设置为true。我可以调用runner.interrupt(),但问题是,由于线程刚刚死亡,我的killAll()函数从未运行过,而我的WebDriver和代理仍在运行。首先,您可能应该捕获InterruptedException,以便您的killAll()方法运行。 只要试一下就行了
第二,为什么不能从main方法中设置stopped=true?如果我理解正确,您会误用while(!stopped)习惯用法。在你的代码中,你检查它是否停止过一次,然后把所有的事情都做到底,设置stopped=true并退出。你只是不给它一个机会在它开始执行后停止执行。当它开始执行时,停止的字段将永远不会再被处理,直到它结束。我会调用
线程。interupt()
在主线程中,并在Runnable
中使用一个循环,以确保调用killAll()
方法
public void run() {
try {
while (!stopped) {
...
}
} finally {
//Run killAll to stop webdriver and the proxy
killAll();
System.out.println("Thread complete");
}
}
将始终调用finally块,即使线程被中断或抛出异常
其他几点意见:
您提到了volatile boolean stopped
标志,但您在循环结束时立即将其设置为true,所以我确实明白了为什么您有一个循环
假设线程没有运行并立即调用killAll()
,那么它挂起在其中一个方法中的某个位置从主线程,正在等待的任何东西都将抛出一个中断异常
。但是由于我没有看到任何捕获正在进行,可能这些方法正在将其作为运行时异常重新抛出
?它们至少应该执行如下操作,但这仍然会阻止异常:
try {
something.wait();
} catch (InterruptedException e) {
// restore the interrupted condition
Thread.currentThread().interrupt();
}
无论如何,try/finally是确保调用
killAll
的正确方法。首先,在(!stopped)和stopped=true时丢失。
public void run() {
try {
while (!stopped) {
...
}
} finally {
//Run killAll to stop webdriver and the proxy
killAll();
System.out.println("Thread complete");
}
}
此外,您还需要在线程中的每个单独阶段计算stopped
(记住运行killAll()并重新启用start按钮).While循环的优点是,我想我把它放进去了,因为我试图找到一种方法从我的Main中停止这个线程。现在我已经删除了它,是的,它运行了一次,但是是否有一个覆盖将它从run()方法和killAll()中删除?该循环中是否有阻塞调用?@Whnunlife如果您发现任何有帮助的答案,您应该向上投票或接受它,即格雷的答案。catch(InterruptedException e){//还原中断条件Thread.currentThread().interrupt();}
如果它是某种while(true),那么它仍然可能正在吞噬异常
loopTrue@artbristol。我已经调整了我的答案。谢谢。问题,这个尝试/捕获,应该在运行中()我的runnable方法正确吗?对。围绕停止的循环。基本上,无论你从开始尝试,最后应该有killAll
。但是回到我的主类,我如何继续更新创建的新线程,并将其设置为“stopped=false”“那么线程将停止?我已经尝试过了,所以我所做的测试是在run()中,删除while语句末尾的stopped=true。所以如果我运行它,它只是一个循环。然后我尝试在单击按钮时从Main设置该值,但循环永远不会退出。如果查看使用“interrupted”的代码,您将看到在run()方法中,它检查interrupted==true并抛出InterruptedException。与您的stopped==true类似。关键是:您决不能强行从另一个线程中断正在运行的线程。如果执行仍然应该运行,您应该在任何时候在run()中签入代码。如果没有-退出或抛出InterruptedException。你可以使用Thread类中存在的isInterrupted()方法,并从主线程调用interrupt()。感谢那里的信息,所以我应该有一段时间(!isInterrupted())然后,如果我调用Thread.interrupt,它将被检查为true并被捕获。我更改了运行()方法,并将每个函数包装在if(!stopped)中,这样,如果我从main中设置stopped=true,则下一个函数将不会运行并调用killAll。我想我让它工作了,看起来像是业余代码,但哦,好吧。