[英]Stop thread anytime i want
我有一个方法,应该中断一个线程,但事实并非如此。 是否需要一直检查while方法中中断的线程来停止线程? 我怎样才能随时终止线程?
solverTh = new Thread(new Runnable() {
@Override
public void run() {
while(somethingistrue){
//do lot of stuff here for long time
}
}
});
solverTh.start();
}
public void terminate(){
if(solverTh != null){
solverTh.interrupt();
}
}
好吧,我认为“很多东西”无关紧要,但我会发布它。 它进行了 openGL 次操作,我将 boolean 变量“终止”添加到它现在工作的代码中,我只是想找到一个更好的解决方案:(glc 是一个 GLCanvas,rotmultiplecube 方法旋转 3 个对象)无论如何我已经解决了这个问题现在,感谢您的回答。
terminated = false;
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(BruteForce.class.getName()).log(Level.SEVERE, null, ex);
}
int colorToBeSolved = Statics.RED_BLUE_TABLE[stateToBeSolved];
System.out.println(stateToBeSolved + "," + colorToBeSolved);
if(entities[0].getColor() != colorToBeSolved){
if(terminated) return;
fullRotate(Statics.FIRST_ROW, Statics.DOWN);
}
if(entities[1].getColor() != colorToBeSolved){
if(terminated) return;
fullRotate(Statics.SECOND_COL, Statics.RIGHT);
}
if(entities[2].getColor() != colorToBeSolved){
if(terminated) return;
fullRotate(Statics.THIRD_COL, Statics.RIGHT);
}
if(entities[3].getColor() != colorToBeSolved){
if(terminated) return;
fullRotate(Statics.SECOND_ROW, Statics.DOWN);
}
if(entities[6].getColor() != colorToBeSolved){
if(terminated) return;
fullRotate(Statics.THIDR_ROW, Statics.DOWN);
}
for(int i = 0; i < 9; ++i){
int col = i % 3;
int row = 3 + i/3;
while(entities[i].getState() != stateToBeSolved){
for(int j = 0;j < 2; ++j){
if(entities[i].getState() != stateToBeSolved){
if(terminated) return;
fullRotate(col, Statics.LEFT);
if(terminated) return;
fullRotate(row, Statics.UP);
if(terminated) return;
fullRotate(col, Statics.RIGHT);
if(terminated) return;
fullRotate(row, Statics.DOWN);
}
}
for(int j = 0;j < 2; ++j){
if(entities[i].getState() != stateToBeSolved){
if(terminated) return;
fullRotate(col, Statics.RIGHT);
if(terminated) return;
fullRotate(row, Statics.UP);
if(terminated) return;
fullRotate(col, Statics.LEFT);
if(terminated) return;
fullRotate(row, Statics.DOWN);
}
}
}
}
}
和全旋转方法:
private void fullRotate(int selectionIndex, int direction){
for(int i = 0; i < 9; ++i){
glc.rotMultipleCubeSlow(selectionIndex, direction);
try {
Thread.sleep(20);
} catch (InterruptedException ex) {
terminate();
}
}
glc.setMovesText(selectionIndex, direction);
glc.setMultipleStateAndColorsByTable(selectionIndex, direction);
glc.isEntitiesRight();
}
while(somethingistrue !Thread.currentThread().isInterrupted()){
//do lot of stuff here for long time
}
不必为阻塞 IO 工作。使用肮脏的技巧:覆盖 Thread.interrupt() 关闭 IO object,导致 IOException 如果处理得当可能会结束线程运行方法。
优雅的解决方案是修改您的 fullRotate() 方法以抛出 InterruptedException。
private void fullRotate(int selectionIndex, int direction)
throws InterruptedException{
for(int i = 0; i < 9; ++i){
glc.rotMultipleCubeSlow(selectionIndex, direction);
Thread.yield();
}
glc.setMovesText(selectionIndex, direction);
glc.setMultipleStateAndColorsByTable(selectionIndex, direction);
glc.isEntitiesRight();
}
你的线程 run() 然后变成:
solverTh = new Thread(new Runnable() {
@Override
public void run() {
while(somethingistrue &&
!Thread.currentThread().isInterrupted()) {
try {
//do lot of stuff here for long time
} catch (InterruptedException ex) {
// handle stop processing
}
}
}
});
solverTh.start();
您还必须从以下内容中删除try catch:
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(BruteForce.class.getName()).log(Level.SEVERE, null, ex);
}
中断线程的唯一方法是让它自己退出。 由于死锁的可能性,在 Java 中甚至没有实现直接中断。 所以你的线程代码必须是这样的:
solverTh = new Thread(new Runnable() {
@Override
public void run() {
while(somethingistrue)
// Do a little stuff here
}
}
});
solverTh.start();
somethingistrue
是线程中断的一种信号。
唯一可以可靠地停止一个线程从另一个线程执行的是操作系统。 所以,选择不多:
1) 向线程发出停止自身的信号。 这个方案有点取决于线程在做什么。 如果它在另一个处理器上运行或卡在无法解除阻塞的阻塞调用上(请注意,可以说服许多阻塞调用提前返回),可能会出现问题。
“很多东西”在做什么?
2) 使用操作系统调用终止线程。 这可能是一个可行的选择,具体取决于线程的作用。 如果有任何可能在线程持有重要资源的公共锁时终止线程(例如,它在 malloc() 的中间并且已锁定内存管理器),那么您可能会遇到麻烦。 您必须确定线程正在做什么才能以这种方式安全地中止它。
3)使用单独的进程来运行“东西”。 这显然可以正常工作,但通常涉及缓慢而痛苦的进程间通信来传递数据和返回结果。
4)设计应用程序,使其不需要终止线程。 有些应用程序不需要终止任何线程,除非在应用程序关闭时,所以没有问题——操作系统可以停止任何东西。 在应用程序运行期间必须“停止”线程并且正在运行长时间的 CPU 密集型操作或被阻塞很长时间且可能不确定的情况下,通过将线程的优先级设置为最小/空闲来“孤立”线程让它最终消亡是另一种常见的方法。
最糟糕的情况是一个线程长时间运行大量的东西,它使用内存管理器或其他公共锁,可能在一个你不知道它在做什么的库中,不能被挂钩和读/写以“孤立”它的方式处理数据意味着无法启动另一个线程来使用该数据。 你真的很笨,你可能不得不终止应用程序并重新启动。 最好避免线程可以进入这样的 state 的设计:)
5) 忘记了 - 如果线程正在使用您可以获得的数据,将某些内容设置为 NULL、0、MaxInt 或其他类似 bodge 的内容可能会导致在运行长内容的线程中引发异常。 当执行从长内容中冒出来时,线程可以检查异常处理程序中的中断 state 并在设置时退出。
当线程正在运行(消耗 CPU 周期)时,默认情况下它不会(自动)响应Thread.interrupt()
。 您将必须编写代码来明确地执行此操作。
将//do lot of stuff here for long time
分成 2 个或更多步骤,并在这些步骤之间插入检查Thread.currentThread().isInterrupted()
- 如果为真 - 中断,否则继续。 这是实现您想要的唯一安全方法。
这取决于长期运行的东西是什么,您将必须设计步骤并决定何时最好检查中断和突破。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.