2016-04-29 117 views
1

我正在編寫一個生成1到1,000之間的隨機數的程序。然後它使用三個線程的線程池搜索範圍更廣的1到1,000範圍內的某些數字範圍。線程檢查其範圍內的每個數字,並將它與隨機目標數字進行比較,如果匹配,則消息傳遞給控制檯。如果號碼不匹配,這也會反映到控制檯的消息中。我想知道如何在達到目標數字後結束程序,並且即使目標已經找到,也不要繼續分析數字。謝謝。如何在Java中停止線程

這是FindIt類:

/** fill in later */ 
public class FindIt extends Thread 
{ 
    private int numToFind; 
    private int numToStart; 
    private int numToEnd; 

    public FindIt(int nF, int nS, int nE) 
    { 
     numToFind = nF; 
     numToStart = nS; 
     numToEnd = nE; 
    } 

    public void run() 
    { 
     int counter = 0; 

     int numAt = numToStart; 

     for (int i = 0; i < (numToEnd - numToStart) + 1; i++) 
     { 
      counter++; 

      if (counter == 10) 
      { 
       counter = 0; 
       Thread.yield(); 
      } 

      if (numAt++ == numToFind) 
      { 
       System.out.println("The target number, " + numToFind + ", has been found by " + Thread.currentThread().getName() + "."); 
      } 

      else 
      { 
       System.out.println(Thread.currentThread().getName() + " has analyzed the number " + (numAt - 1) + " - not the target number."); 
      } 

     } 
    } 
} 

這是主要的方法的程序:

import java.util.Random; //imports Java's Random class 
import java.util.concurrent.*; 

/** fill in later */ 
public class NumberSearch 
{ 
    public static void main(String [] args) 
    { 
     Random r = new Random(); //creates an instance of the Random class 
     int randomNum = r.nextInt(1001); //declares the integer randomNum and initilizes it to be a random interger in the range 0 inclusive to 1001 exclusive 

     ExecutorService executor = Executors.newFixedThreadPool(3); 

     FindIt find1 = new FindIt(randomNum, 0, 349); 
     FindIt find2 = new FindIt(randomNum, 350, 699); 
     FindIt find3 = new FindIt(randomNum, 700, 1000); 

     executor.execute(find1); 
     executor.execute(find2); 
     executor.execute(find3); 

     executor.shutdown(); 
    } 
} 
+1

的可能的複製[?如何正確地停止在Java線程(http://stackoverflow.com/questions/10961714/how-to-properly-stop -ja-thread-in-java) –

+0

@Ravindrababu:請注意,在該問題上接受的答案不能處理任務在線程池中運行的情況,當使用Executors時,整個手動滾動易失性標誌方法失敗。 –

+0

好的。我撤回了我的投票。 –

回答

4

兩個方面的要求:

  • 使您的工作響應通過檢查Thread.currentThread().isInterrupted()並在檢測到中斷時使任務返回來中斷。

  • 使用ExecutorService的shutdownNow方法來中斷當前正在運行的任務。關閉方法使執行程序停止接收新任務,但讓已經提交給執行程序的任務運行完成。

別子線程對於這一點,你應該以確定提交給執行器的任務將觸角延伸Runnable或贖回。子類化線程意味着任務分配一個OS線程,這是不必要的,因爲實際線程已經在線程池中創建。對於這個例子,因爲你正在計算任務中的數字,所以使用Callable可能是有意義的。

在java.util.concurrent中有一個現有的類是爲這種類型設計的。 API documentation for ExecutorCompletionService給出了一旦找到答案就取消任務的例子。

FindIt改變檢測中斷:

public class FindIt implements Runnable 
{ 
    private int numToFind; 
    private int numToStart; 
    private int numToEnd; 

    public FindIt(int nF, int nS, int nE) 
    { 
     numToFind = nF; 
     numToStart = nS; 
     numToEnd = nE; 
    } 

    public void run() 
    { 
     int counter = 0; 

     int numAt = numToStart; 

     for (int i = 0; i < (numToEnd - numToStart) + 1; i++) 
     { 
      if (Thread.currentThread().isInterrupted()) { 
       System.out.println(Thread.currentThread().getName() 
       + " detected interruption, exiting"); 
       return; 
      } 
      counter++; 

      if (counter == 10) 
      { 
       counter = 0; 
       Thread.yield(); 
      } 

      if (numAt++ == numToFind) 
      { 
       System.out.println("The target number, " + numToFind + ", has been found by " + Thread.currentThread().getName() + "."); 
      } 

      else 
      { 
       System.out.println(Thread.currentThread().getName() + " has analyzed the number " + (numAt - 1) + " - not the target number."); 
      } 

     } 
    } 
} 
+0

這使得shutdownNow()正常工作,但我不能立即調用它沒有線程停止即刻。如何找到號碼時調用shutdownNow()? –

+0

@ B.Freeman:您可以等到打電話給shutdownNow,直到您有答案。我做了類似的事情,但沒有執行者[here](http://stackoverflow.com/q/36872621/217324)。但在這種情況下,我會使用Future,並在未來返回時調用shutdownNow。這裏也是[使用Future和Callable的答案](http://stackoverflow.com/a/35563988/217324)。 –