[英]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.