2016-04-29 121 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)。 –