2010-12-20 4 views
10

は、私は、次のクラスがあると仮定:guava-libraries:Iterators.cycle()はスレッドセーフですか?

public class Foo { 

    private List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5); 
    private Iterator<Integer> iterator = Iterators.cycle(list); 

    public void bar(){ 
     Integer value = iterator.next(); 
     doSomethingWithAnInteger(value); 
    } 
} 

はFooのインスタンスが二つのスレッドにより同時にacessedされている場合、私は、各スレッドがiterator.next()異なる値を取得することを必要とします。 bar()メソッドを同期させる必要がありますか?またはiterator.next()はスレッドセーフであることが保証されていますか?

この例では、基本的なIterableとしてArrayListを使用しています。サイクリックイテレータのスレッドセーフティは、特定の反復可能な実装に依存しますか?

ありがとうございます。

答えて

11

グアバでは、何も書かれていない限り、スレッドセーフであることはほとんど保証されていません。

バーメソッド全体を同期させる必要はありませんが、iterator.next()の呼び出しを同期ブロックでラップする必要があります。例えば:

public void bar(){ 
    Integer value; 
    synchronized (iterator) { 
     value = iterator.next(); 
    } 
    doSomethingWithAnInteger(value); 
} 
6

Iterators.cycle(final Iterable<T> iterable)source codeを見てみましょう。基礎となるIteratorがスレッドセーフであっても、サイクリングラッパーのようには見えません。これは、イテレータを暗黙的に同期させないというJavaの方針と一貫しています。

関連する問題