2016-07-22 18 views
-1

同時に2つのExecutorServiceを起動したいとします。私のメインの中に例えば複数のExecutorService Javaを起動する

、:

MyClass.firstAsync(); 
MyClass.secondAsync(); 

と、

public void firstAsync() { 
ExecutorService service = Executors.newFixedThreadPool(4); 
    service.submit(new Runnable() { 
     public void run() { 
      while (true) { 
       System.out.println("I m running : First Async"); 
     } 
    }); 
} 

その後、

public void secondAsync() { 
    ExecutorService service = Executors.newFixedThreadPool(4); 
     service.submit(new Runnable() { 
      public void run() { 
      while (true) { 
       System.out.println("I m running : Second Async"); 
       } 
     }); 
    } 

問題がある。第二のクラスが呼び出されたときに、それが行われます最初のだから私はこの出力を持っている:

I m running : First Async 

二ExecutorServiceのが立ち上げたが、2番目の起動時に、私は、この出力

I m running : Second Async 

を持ってis'ntながら。

私も同じサービスにそれらを入れてみました(同じExecutorServiceの上の2つのservice.submit(...)を持っている)が、それは私が欲しいものすべて

では動作しませんが、両方の出力であります、 同時に"。

ありがとう、 クレアメント。

+0

最初に2つのスレッドプールが必要なのはなぜですか? – TMichelsen

+3

私はあなたの質問を理解しません。あなたのアイデア/要求の背後にあるかもしれない問題もありません。 – GhostCat

+0

私のプログラムはそうです。最初の関数は2番目の関数と同じことをしません(私の実際のメインで) – Souin

答えて

1

スレッドの実行を制御することは期待できません。あなたはそれをシミュレートしたい場合は 、のは、あなたのループでご紹介しましょう:

Thread.sleep(10); 

これは、スリープ状態に、現在実行中のスレッドを強制し、実行する他のスレッドにチャンスを与えます。

しかし、スレッドの実行を調整することは期待しないでください。

+0

しかし、私の2つの機能、reallityで、サーバーにいくつかの情報を聞く。だから私はサーバーが何を言いたいのかを知るためには両方の機能が必要です。 問題は、最初の機能がブロック状態であり、2番目の機能もブロック状態です。だから私はこの機能を分離する必要があり、私はこの機能が毎回起動され、他の機能をブロックする必要はありません – Souin

+0

クレメント、あなたのマシンにコアが1つしかありませんか?それ以外の場合は、別のスレッドで実行すると同時に実行されます。 –

1

あなたのコードは意図したとおりに動作します。私はあなたがこのような出力を得ることを期待想定しています:

I m running : First Async 
I m running : Second Async 
I m running : First Async 
I m running : Second Async 

しかし、その代わりに、あなたが得る:

I m running : First Async 
I m running : First Async 
... 
I m running : First Async 
I m running : Second Async 
I m running : Second Async 
... 
I m running : Second Async 
I m running : First Async 
... 
I m running : First Async 
I m running : Second Async 
... 
I m running : Second Async 

そして多分あなたは、あなたがからの出力が表示されないことを一つのスレッドからそんなに出力を取得していますもう片方。

これは、両方のスレッドが同じ出力ストリーム(System.out)上でアクセスするために競合するために発生し、他のスレッドがストリームに対して許可を得る前に複数の行(数千も)を印刷するように管理します。

これをテストするには、ループに遅延を追加してください。各スレッドは一度に1行しか印刷できません。

while (true) { 
    System.out.println("I m running : First Async"); 
    Thread.sleep(100); // <---- and surround with try-catch 
} 
while (true) { 
    System.out.println("I m running : Second Async"); 
    Thread.sleep(100); // <---- and surround with try-catch 
} 
+0

それは本当に私の問題ではありません。私の問題は次のとおりです。第2の非同期関数が起動されると、最初のものが閉じられます。 – Souin

+0

@ClémentB最初のものが本当に閉鎖されていて、出力を誤解していない場合は、投稿したコードにこの問題の原因は含まれません。遅延を使用してみて、動作しない場合はコードを投稿してください –

+0

ブレークポイントでコードをデバッグしようとしましたか? –

0

(1)あなたのコードは大丈夫です(いくつかのマイナーな発言は除きます)。実際のコードが速すぎて同時性に気づかないことが問題です。さらに、printlnは通常は同期化されます。各 "run()"を複数の行を出力するループに置き換えると、並行性に気付くでしょう。

(2) (a)2つのスレッドプールが本当に必要ですか?理由は、例から明らかではないということだけです。(b)スレッドプールをローカルメソッド変数としてインスタンス化することに意味がないので、再利用できる場所に配置する必要があります+監視された+終わりのいつか。明らかに、議論のためにコードを簡略化しただけかもしれません...

+0

私は同じExecutorServiceでも試しましたが、それでも動作しません:/ – Souin

+1

実際にコピーして実行しました。私は単なる "println"を100 "println"のループに変更しました...そしてそれはうまく動作し、混合出力を生成しました。実際に試しましたか?私が言及したように、あなたは1つの 'println'との並行性は見ません.... –

+0

@私の最終回答:)ありがとうございます。 – Souin

0

私はコメントをしたいと思いますが、明らかにstackoverflowで50の評判が必要です(共鳴的ですが、残念です)。だから私はこの質問に答えるつもりです。

ExecutorServiceは、Executorインターフェイスを実装するマネージメントオブジェクトを意図しています。つまり、ExecutorServiceはその中にスレッドプールを保持できます。スレッドプールは、さまざまなRunnableスレッドオブジェクトをホストするために使用できます。彼らは同じタイプのものでなければならない。

たとえば、特定の関数を持つRunableクラスがある場合、スレッドが汎用的であるため、ExecutorServiceが保持するスレッドからそのクラスを起動できます。後でそれらとやり取りする特定のスレッドを特定する必要がある場合は、各Runnableスレッドタイプにgetterメソッドを持つ特定の不変の識別子クラスフィールドを持つことができます。または、必要に応じて、スレッドオブジェクトを構築するときにスレッドオブジェクトへの参照を格納することができます。

また、実行中のスレッド/スレッドグループとそのIDを見つける機能もあります。あなたの質問への答えは、あなたが2 ExecutorServicesを持っている必要はないということです

http://nadeausoftware.com/articles/2008/04/java_tip_how_list_and_find_threads_and_thread_groups#GettingThreadGroups

:あなたはここで、この方法を見ることができます。静的または動的な方法でスレッドプールのサイズを設定することができ、スレッドプールはhetrogeneousスレッドオブジェクトをホストできます。

こちらがお役に立てば幸いです。そして、これが適切な答えであることを願っています。

+0

さて、ちょうど他のすべての答えを見た。エグゼクティブをあなたのメソッドにローカルに保存することなく、クラスフィールドとして(実際に必要な場合)保管することは可能でしょうか? –

0

ここは私の最終回答です。

私のfirstAsync()コードでは、NullPointerExceptionがコンソールに表示されていませんでした。

私はそれを理解するために私のサービスから男と1時間以上をパットしました。それは私の悪いです。 あなたの答えはすべて良かったし、私の質問はばかだ。

ありがとう、Clément。

関連する問題