1

タイトルが示すように、0 から MAX_LIMIT までのすべての素数を見つけようとしています。

入力例: javac Main.java 8 100

これは、8 つのスレッドを作成し、100 を含む 0 から 100 までの素数を見つけることを意味します。私のプログラムは 2 つのコマンド ライン引数を取ります。1 つ目はスレッドの数、2 つ目は素数の範囲 (0 から n) です。

出力例:

素数: 2 スレッド番号: 13

素数: 7 スレッド番号: 15

素数: 7 スレッド番号: 16

素数: 11 スレッド番号: 18

:

その後、システムがハングし、プロセスを停止する必要があります。

プロセスは終了コード 137 で終了しました

私の質問は:

スレッド プールが制限 (1 ~ 8 ではなく、13 または 16 のようなスレッド番号) を超えるのはなぜですか? また、すべてのスレッドが同時に同じ番号を計算しないようにするにはどうすればよいですか? 配列リストに数値を追加するなど、何らかのキャッシュを使用することを考えていますが、それが正しいアプローチであるかどうかはわかりません。

ThreadPool とは何かを誤解していて、実際にはまったく関係のないものを使用している可能性があります。

この場合、ハングしていて、0 から 100 までのすべての素数が出力されない理由もわかりません。

私がやろうとしていることをもっと簡単に行う方法があれば、それを聞いてみたいと思います。

私はここでこれに取り組んでおり、このスレッドを頻繁に確認します。

はい、これはスレッドに関するオペレーティング システム クラスの宿題です。通常は助けを求めることはありませんが、途方に暮れています。すべてのコードは 1 つのファイルにあります。

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

public class Main {

private static int MAX_THREADS;
private static int MAX_LIMIT;
private static int numToTest = 0;

public static void main(String[] args) {

int max_threads = Integer.parseInt(args[0]);
int max_limit = Integer.parseInt(args[1]);

MAX_THREADS = max_threads;
MAX_LIMIT = max_limit;

Foo();
}



private static void Foo() {

    class PrimeNumberGen implements Runnable {

        int num = numToTest;

        PrimeNumberGen(int n) {num = n;}

        boolean isPrime(int n) { //first test is 0
            if(n<2) return false;
            if(n==2) return true;
            if(n%2==0) return false;

            int max = n/2;
            for(int i=3; i< max; i=i+2) {
                if (n % i == 0)
                    return false;
            }
                    return true;
        }




        public void  run() {
            numToTest++;
            if(isPrime(num)) {

                System.out.println("Prime Number: "+num+" Thread #:
          "+Thread.currentThread().getId());

            }
            else {
                numToTest++;
            }

        }
    }
    //Thread t = new Thread(new PrimeNumberGen(num));
    //t.start();
    ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS);
    for (int i = 0;i <= MAX_LIMIT; i++) {
        Runnable worker = new PrimeNumberGen(numToTest);
        executor.execute(worker);
    }


 }
}
4

4 に答える 4

3

質問の 2 番目の部分については、エラトステネスのふるいをご覧ください。

変化する

Runnable worker = new PrimeNumberGen(numToTest);

Runnable worker = new PrimeNumberGen(i);

numToTest実際には、もう必要ないこの変数を捨てることができます。

于 2013-09-28T03:16:20.480 に答える
3

スレッド ID は、スレッドの一意の番号です。これは任意の番号から開始でき、連続している必要はありません。スレッド プールの存続期間中は、最大数を超えるスレッドを持つことができますが、常に最大数を超えることはできません。

ところで、複数の素数を見つける必要がある場合は、エラトステネスのふるいを使用すると、時間の複雑さが軽減されるため、はるかに高速になります。通常はシングル スレッドですが、それでも高速です。

于 2013-09-28T03:16:28.173 に答える