1

1 から 1,000 の間の乱数を生成するプログラムをコーディングしています。次に、3 つのスレッドのスレッド プールを使用して、より広い 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

次の 2 つが必要です。

  • 中断が検出されたときにタスクをチェックThread.currentThread().isInterrupted()して戻すことにより、タスクを中断に応答させます。

  • 現在実行中のタスクを中断するには、ExecutorService の shutdownNow メソッドを使用します。shutdown メソッドは、エグゼキューターが新しいタスクの受信を停止するようにしますが、エグゼキューターに既に送信されたタスクは完了するまで実行します。

このために Thread をサブクラス化しないでください。Executor に送信されるタスクを定義するには、Runnable または Callable を拡張する必要があります。スレッドのサブクラス化は、タスクが OS スレッドを割り当てることを意味します。実際のスレッドはスレッドプールに既に作成されているため、これは不要です。この例では、タスクで数値を計算しているため、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 に答える