2

私はパッケージjava.util.concurrentを初めて使用します。マルチスレッドとモノスレッドの戦略を使用して、数値が素数であるかどうかをテストする次のプログラムを作成しました。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class IsPrime
        implements Runnable
    {
    private static final long UPPER_BOUND=100000;
    long value;//the number observed
    private IsPrime(long value)
        {
        this.value=value;
        }
    /** returns wether value is a prime number (simple and stupid method ) */
    private boolean isAPrimeNumber()
        {
        if(value==1 || value==2) return true;
        if(value%2L==0) return false;
        for(long i=3;i< value;++i)
            {
            if(this.value%i==0) return false;
            }
        return true;
        }

    @Override
    /** calls isAPrimeNumber */
    public void run()
        {
        boolean result=isAPrimeNumber();
        //if(result) System.out.println("["+this.value+"]");
        }

    /** loop from 3 to UPPER_BOUND, multithreaded */
    private static long loopMT() 
        {
        long now=System.currentTimeMillis();
        ExecutorService service=Executors.newFixedThreadPool(10); 

        for(long i=3;i< UPPER_BOUND;i+=2)
            {
            service.submit(new IsPrime(i));
            }
        service.shutdown();
        return System.currentTimeMillis()-now;
        }

    /** loop from 3 to UPPER_BOUND, NOT multithreaded */
    private static long loop() 
        {
        long now=System.currentTimeMillis();
        for(long i=3;i< UPPER_BOUND;i+=2)
            {
            new IsPrime(i).run();
            }
        return System.currentTimeMillis()-now;
        }

    public static void main(String[] args)
        {
        long n1=IsPrime.loop();
        long n2=IsPrime.loopMT();
        System.out.println(""+n1+" >>> "+n2);   
        }
    }

メソッドloopMTの場合、パッケージjava.util.concurrentのクラスを使用する正しい方法ですか?このプログラムを書くための別の(より安全で、よりエレガントな)方法はありますか?マルチスレッド環境でSystem.outを使用できますか?

あなたの提案に感謝します

ピエール

4

3 に答える 3

2

そのSystem.out一例として、PrintStreamスレッドセーフです。したがって、例のトレーニングには問題ありません。しかし、一般的に、異なるスレッドからの出力は私には良い考えではないようです。非同期で出力の要求を受け入れる専用の出力スレッドを用意することをお勧めします。

おそらく、私はCallable<Boolean>finnwが提案したように実装したいと思います。そうでなければIsPrime、CPUの消費を除いて、クラスに理由はありません。

于 2010-01-28T09:57:17.733 に答える
1

現在書かれているようloopMTに、提出されたタスクが完了するのを待っていません。

いくつかのオプションがあります。

  • 呼び出して、すべての素数性テストが完了するのを待ち、現在行っているようawaitTermination()に結果を書き込みます。System.out
  • インターフェイスをRunnableからCallable<Boolean>または多分に変更してCallable<Map.Entry<Long, Boolean>>使用しますservice.invokeAll()(そうすると、すべての結果が一度に返されます)。
  • 結果を同期Mapして保存し、すべての素数性テストが完了したらそれを読み取ります
  • メソッドに結果をまたはrunに送信させ、メソッドループにキューから結果をフェッチして出力させます。これは私が好むオプションです。BlockingQueueSynchronousQueueloopMT
  • を介して間接的にキューを使用しますCompletionService
于 2010-01-28T09:54:21.763 に答える
1

この計算はCPUにバインドされている可能性が高いため、CPUコアよりも多くのスレッドを実行する利点はありません。その後の余分なスレッドは、オーバーヘッドを増やすだけです。

于 2010-01-28T09:54:53.803 に答える