2016-11-01 6 views
0

スレッドを作成するとき、私は最初のケースと2番目に何を得ますか?Javaでスレッドを作成します。

一般に、それらの間に違いがありますか?あなたは一つのスレッドのインスタンスを作成し、5つの別のスレッドのインスタンスを作成し、それらを実行しようとしている第二に、それを5回実行しようとしている最初のケースで

ExecutorService executorService = Executors.newCachedThreadPool(); 

NewThread newThread = new NewThread(Thread.MAX_PRIORITY); 
for(int i = 0;i < 5; i++){ 
    executorService.execute(newThread); 
} 

ExecutorService executorService = Executors.newCachedThreadPool(); 

for(int i = 0;i < 5; i++){ 
    NewThread newThread = new NewThread(Thread.MAX_PRIORITY); 
    executorService.execute(newThread); 
} 
+0

あなたの 'run()'メソッドが何をするかによって異なります。注:どちらの場合でも 'NewThread'を起動していないので、実際には実行されません。 Threadオブジェクトを作成することは、それを開始することと同じではありません。 –

+2

あなたが得ることは、NewThreadのコードに完全に依存します。 –

答えて

0

。それはあなたの質問に答えますか?

+0

ああ、ありがとう! –

0

I あなたの質問は悪い命名に根ざしています。あなたは

executorService.execute(newThread); 

をやっているし、おそらくあなたは、なぜ(スレッドプールに基づいています)、そのサービスがスレッドを扱っているか、今思っています。

かんたん回答:ありません。そのインタフェースExecutor.execute()実行可能ファイルオブジェクトをとります。言い換えれば

:あなたのコードは、実行方法あなたのクラスNewThreadが提供する呼び出します。

あなたの質問に対する「直接」回答は、最初のケースではと同じ実行者を実行者に5回送信しています。 2番目のケースでは、5 異なるランナブルをエグゼキュータに送信しています。

の意味で異なる:異なるオブジェクト - 彼らは同じクラスであると、非常に同じことは、両方の例については起こるはず。あなたがいくつかの厄介なことをしない限り、スタティック NewThreadのもの;あなたの質問の全体的な印象を考えるとあまり驚くべきことではありません。

+0

はい、あなたが正しいです、私は私の質問に間違った名前が付けられていることを理解しました、ありがとう。 –

0

私はそれを試していませんが、最初のケースは一度実行してから例外をスローする必要があります。 Threadのインスタンスが終了すると、それを再開しようとするのは不正です。 See the javadoc for start

IllegalThreadStateException - スレッドがすでに開始されている場合。

2つ目の例は、5つの別々のスレッドインスタンスを作成しているので、2つ目の例のほうが賢明です。

+0

あなたの答えをありがとうが、最初のケースと2番目のすべてが正常に実行された場合。私は質問があります。 –

1

あなたが提供したことを考えれば、最初のケースではおそらくエラーが発生します。第二の方法は完全に安全です(あなたが安全でない何かをしていないと仮定して)。

私は、あまり有用ではない知っているので、のはあなたにいくつかの背景を取得してみましょう。

class NewThread implements Runnable { 
    void run(){ 
      //do something 
    } 
} 

今、私たちは実際の実装だか分からないが、我々はまだいくつかの分析を行うことができます。それは、このような方法のボイドの実行を()、持っている必要がありますので、

NewThreadはおそらく、Runnableを実装しています。あなたの例の全体的な結果は、NewThreadがステートフルかステートレスかによって異なります。 「ステートフル」は、そのクラスのインスタンスが状態を持つことを意味します。たとえば、いくつかの内部フィールド(属性)。 「ステートレス」は単に「ステートフル」ではありません。

NewThreadがステートレスである場合、どちらの場合も結果は同じになります。ExecutorServiceの下に新しいスレッドでrun()メソッドが実行されますが、変数の状態はとにかくありません。

NewThreadがステートフルな場合は、最初の例に問題がある可能性があります。コードはOKですが、ロジックが壊れている可能性があるため、ここではあまり役立たないでしょう。これを想像してみましょう:

class NewThread implements Runnable { 
    int x = 0; 
    void run(){ 
      while (x<10) 
       x = x + 1; 
    } 
} 

ここに表示されているのは、競合状態のハンドブックの例です。私よりも優れた作者が私よりも問題の方が良いと説明していますので、thisthisthisなどのリンクをいくつか提供しています(もちろん:もちろんGoogleを使用してください)。基本的には、この場合の競合状態は、x = x + 1を実行するときは、最初にxを読み出してから書き込む必要があるということです。読み取りと書き込みの間に、他のスレッドがxの値を変更した可能性があります。これはこのスレッドによって上書きされます。

NewThreadはステートフルですが、正しく動作する場合があります。あなたはで手にコードを同期させる場合に発生します - synchronizedキーワードを使用して(例えば、上記の第三のリンクを参照)、または同期されたデータ構造を使用して、次のいずれか

class NewThread implements Runnable { 
    AtomicInteger x = new AtomicInteger(0); 
    void run(){ 
      while (x<10) 
       x.incrementAndGet(); //getAndIncrement would work too - we don't care about the result, only about incrementing 
    } 
} 

「アトミック」は、そのクラスのすべての操作が考慮されることを意味し(x = x + 1は2つのステップですが、これはまさに競合状態につながります)。利用可能な原子クラスはすでにいくつかありますin JDK。あなた自身も同様のことを実装したい場合は、synchronized keywordまたはlock-like objectを使用して変数を保護している可能性があります。

関連する問題