2017-04-14 14 views
2

には2つのオプションスレッドごとに新しいCallableオブジェクトを作成する必要はありますか?ここ

1)1コーラブル作成し、それを複数回

Callable<String> callable = new MyCallable(); 
     for(int i=0; i< 100; i++){ 
      Future<String> future = executor.submit(callable); 
      list.add(future); 
     } 

2を提出)各スレッド

for(int i=0; i< 100; i++){ 
     Future<String> future = executor.submit(new MyCallable()); 
     list.add(future); 
    } 

のベストプラクティスとは何であるため、複数の呼び出し可能オブジェクトを作成していますか?あなたのMyCallableあるスレッドセーフなクラスが、あなたはそれの同じインスタンスを再利用することができた場合は

+0

異なる呼び出し可能オブジェクトが必要です。 – jn1kk

+0

ありがとうございます。これは私が思ったことです。しかし、私を混乱させる例がhttp://www.journaldev.com/1090/java-callable-future-exampleです。 1つの呼び出し可能なものを使用します – john

+1

@ jn1kk - それはそのクラスが何をするかによって異なります。複数のスレッドから同じCallableを呼び出すことに本質的に間違っていることはありません。 –

答えて

4

、そうでない場合、あなたは競合状態と矛盾する結果となってしまいます。

つまり、MyCallableが正しく同期されていない状態を保持しようとすると、同じインスタンスを使用することはできません。あなたはAtomicIntegerintを交換した場合のに対し

//Non-Thread Safe Callable implementation 
public class MyCallable implements Callable<String> { 

    private int i; 

    @Override 
    public String call() throws Exception { 
     i++; //RACE CONDITION 
     System.out.println(i); 
     return String.valueOf(i); 
    } 
} 

:たとえば

MyCallableクラスの下に、あなたは、複数のスレッド(つまり、あなたはexecutor.submit(singleInstance)ようにそれを共有することはできません)間で同じインスタンスを再利用することはできません以下に示すように、あなたは同じインスタンスを再利用することができます

//Thread Safe Callable implementation 
public class MyThreadSafeCallable implements Callable<String> { 

    private AtomicInteger i = new AtomicInteger(0); 

    @Override 
    public String call() throws Exception { 
     int value = i.incrementAndGet(); 
     System.out.println(value); 
     return String.valueOf(value); 
    } 
} 

ので、ここで注意すべき重要な点は、あなたがCallable、Yの同じインスタンスを再利用したい場合は、ということですスレッドセーフであることを保証する必要があります。それ以外の場合は、に複数のCallableインスタンスを送信する必要があります。

関連する問題