1

我正在编写一个程序,该程序会生成一个介于 1 到 1,000 之间的随机数。然后它使用三个线程的线程池来搜索更广泛的 1 到 1,000 范围内的某些数字范围。线程检查其范围内的每个数字,并将其与随机目标数字进行比较,如果匹配,则向控制台发送消息。如果数字不匹配,这也会反映在发送到控制台的消息中。我试图弄清楚一旦达到目标数字如何结束程序,即使已经找到目标也不会继续分析数字。谢谢你。

这是 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." );
            }

        }   
    }
}

这是带有 main 方法的程序:

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();
    }
}
4

1 回答 1

4

需要两件事:

  • 通过检查Thread.currentThread().isInterrupted()并在检测到中断时让任务返回,使您的任务对中断做出响应。

  • 使用 ExecutorService 的 shutdownNow 方法来中断当前正在运行的任务。shutdown 方法使 executor 停止接收新任务,但让已经提交给 executor 的任务运行完成。

不要为此子类化 Thread,您应该扩展 Runnable 或 Callable 以定义提交给 Executor 的任务。子类化线程意味着任务分配一个操作系统线程,这是不必要的,因为实际线程已经在线程池中创建。对于此示例,由于您正在计算任务中的数字,因此使用 Callable 可能是有意义的。

java.util.concurrent 中有一个现有的类是为这种事情设计的。ExecutorCompletionService 的 API 文档中给出了一旦找到答案就取消任务的示例。

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." );
            }

        }   
    }
}
于 2016-04-29T16:43:10.783 回答