2012-01-08 11 views
4

私が取り組んでいるプログラムでは、ユーザーがスレッドの数の間でプログラムが作業負荷を分けることができるように、そのプロセッサが持つ処理スレッドの数を入力できるようにしたい(一般的な計算を行っている)コンピュータは持っています。ユーザ定義のスレッド数はどのようにして作成しますか?

また、システム構成を検出してユーザーに質問せずにスレッド数を取得する方法がありますか?これは望ましいことですが、これを行う方法があるかどうかわかりません。

私が考えることができたのはここだけです。私はそれが完全に間違っていることを知っています、そして、あなたはそのようにスレッドに名前を付けることはできませんが、私は初心者です(まだ高校時代です)、私は試していることを示すために何かを入れたかったのです。それはIntelのハイパースレッディングを使っている場合、私は、二度、私はコア数別名、コンピュータが持っているスレッドの数を作成しようとしている、と言って、またはてるかわからない

for(int i = 0; i < threads; i++) { 

    Thread thread(i) = new Thread(){ 
     public void run() { 
      double endNum = 0; 

      for(double numberRun = 0; numberRun <= calcs/threads; numberRun++){ 
       endNum += (num * 999999999); 
      } 

      System.out.println("Thread " + i + " complete! The numerical result of the calculation is " + endNum); 
     } 
    }; 
} 

みんなコアの数。システムが一度に実行できるスレッドより多くのスレッドを持つことができますが、私は最も効率的なことを行い、システムの同時実行が可能なスレッドの数に計算の総数を割ります。ユーザーにスレッド数を定義させてから、その数のスレッドを作成させる(またはプログラムがスレッド数を決定してその数を作成させる)方法を知らない。

+6

これをチェックしましたか:http://stackoverflow.com/questions/1980832/java-how-to-scale-threads-according-to-cpu-cores – home

+0

あなたも固定しないと意味がありませんコア/ HTでも、あなたのスレッドが現代のマルチタスクOSで一人ではないことを知っておく必要があります。ほとんどの場合、オペレーティングシステムのスケジューラが何を実行するかを決めるほうがはるかに優れています。システムの他のスレッドが何をしているのかを知る方法がなく、あなたのスレッドの1つをコアに固定することができれば、パフォーマンスが低下する危険性がありますが、それはかなりうまくいくでしょう。 – Fredrik

+0

@Fredrik - CPU集約的なタスク(これはマシン上で唯一または最も一般的なものと仮定します)では、一般にCPUよりも多くのスレッドを実行する必要はありません。しかし、あなたはそれらのすべてを使用していないので、CPUの数を減らしたいとは思わない。 nCPUIntensiveThreads == nProcessorsは実際にかなり公平なターゲットです。 – James

答えて

0

スレッドの数はプロセッサに依存しません。シングルプロセッサを使用している場合、プログラマはあるスレッドから別のスレッドにジャンプします。

したがって、あなたのメソッドには何も「間違っている」ことはありません(もちろん、正しく使用する場合)。

+0

最適なスレッド数は確かにCPUのバウンドやパフォーマンスに重大な影響を及ぼす場合は、プロセッサの数に依存します。 – James

+0

@ジェームスだから、それはCPUの性能に依存する –

0

私はシステムが持つことができるスレッドの最大数について質問していると思いますか?

hereで説明したように、システムには最大スレッド数はありません(Java仮想マシンの内部でJavaプログラムが実行されるため、Java仮想マシンの制限であるJVM)。制限は、スレッドに割り当てることができるリソースの量に制限されます。

現在実行中のスレッド数(外部プログラムやJVM内で起動されている可能性があります)を確認するには、おそらくそれを見つけることができますが、起動するスレッドがシステム内で実行されている他のスレッドと何ら関係していないので、あなたのケースで使用してください!

+0

実際には、合理的に使うことができるより多くのスレッドをほぼ確実に割り当てることができます。数千人以上の人の後で、CPU間の切り替えだけで相当量のCPUを使うようになります。 – James

1

私が使いたいものは ExecutorService executor = Executors.newFixedSizeThreadPool(int numberOfThreads);です。

executor.execute(myRunnable)を実行します:)この方法では、スレッドを作成する責任がなく、不要なスレッドを作成しないという保証があります。

しかし、どのように多くのスレッドを使用すべきかを把握する方法については、それはあなたの研究の責任です。あなたはどのように多くのプロセッサを見つけることができ

4

は、このようなJVMに用意されています

Runtime.getRuntime().availableProcessors() 

上純粋な数値計算を分割するスレッドの最適な数は、おそらくプロセッサごとに一つです。これらのスレッドのいずれかがIOで時々ブロックされなければならない場合は、それ以上である可能性があります。

+0

しかし、ユーザーのコンピュータに搭載されているスレッド数を作成するにはどうすればよいですか?これは、多くの異なるシステム構成で実行できるようにするためのもので、プログラムは適切な数のスレッドを自動的に作成することになっています。 – user1137371

+0

@ user11373731 - 私はあなたのコメントにスレッドとプロセッサーを混ぜていると思います。上記のコマンドは、使用可能なプロセッサの数を示しています。これは、一般的なスレッドの数です。 – James

+0

@James - 私は、プロセッサの数もあなたが望むスレッドの数であることを知っていますが、その数に基づいて計算を実行するプログラムを取得する方法を知りません。そのコードスニペットの結果 – user1137371

2

あなたは異なる明確なタスクの束を実行するつもりなら - 並列に実行する複数の小さなタスクに一つの大きなタスクを分割しようとは対照的に、あなたはExecutorを使用することがあります:

Executor e = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); 
// run a single task 
e.execute(new Runnable() { 
    public void run() { 
     // do stuff here 
    } 
}); 

他の人が指摘しているように、スレッドプールの最適なサイズは、タスクの入出力量などのさまざまな要因に依存しますが、使用可能なコアの数は適切なデフォルト値でなければなりません。

+0

私は1つを分割しようとしていますすべての利用可能な処理スレッドの間で大きなタスク(繰り返し式を実行する)。 – user1137371

+0

@ user1137371それでは、スレッドを直接使用するかexecutorを使うかは問題ではありませんが、私はまだFuturesのために後者が好きです。 Runnableの本体では、あなたの質問からメソッド本体を使用することができ、 'threads'の値は' Runtime.getRuntime()。availableProcessors() '(またはあなたが適切と考えるもの)になります。 – millimoose

3
class Task implements Runnable { 
    Task(/** Whatever you need to identify the subset of tasks to run goes here*/) { 

    } 

    public void run() { 
    // do the calcs 
    } 
} 

int nProcs = Runtime.getRuntime().getAvailableProcessors(); 

Task[] tasks = new Task[nProcs]; 
for (int i = 0; i < nProcs; i++) { 
    tasks[i] = new Task(/** Whatever parameters for this batch*/); 
    new Thread(tasks[i]).start(); 
    // Alternatively, use Executors.newFixedThreadPool() to get a service above, and submit the runnable there, getting a future for the result, something like this: 
    Future f = executor.submit(task[i]); 
} 

}

+0

James、there is私はあなたにこれについてメールすることができるチャンスですか?いくつかのコードといくつかのコードがありますが、ここでは少し難解です。時間がある場合は、[email protected]までメールしてください – user1137371

1

あなたが探していることも、スレッドへのタスクのマッピング戦略であるように私には思えます。例えば、のようなループ:

ExecutorServiceが取る
ExecutorService exec = Executors.newCachedThreadPool(); 
for(int i = 0; i < LARGE_NUMBER; i++) { 
    exec.submit(new Task(i)); 
} 

exec.awaitTermination(1000, TimeUnit.HOURS); // wait for all tasks to finish 

:次いで、ループの初期を置き換える

class Task implements Runnable { 
    private int i; 

    public Task(int i) { 
     this.i = i; 
    }  

    public void run() { 
     f(i); 
    } 
} 

for(int i = 0; i < LARGE_NUMBER; i++) { 
    f(i); 
} 

のような並列バージョンに変換することができます。使用可能なプロセッサに関して適切な数のスレッドを使用すること、およびタスクがオンデマンドで実行されるようにスレッドをリサイクルすることの注意が必要である。

関連する問題