2016-12-15 8 views
-1
public class ListHelper<E> { 
    public List<E> list = 
    Collections.synchronizedList(new ArrayList<E>()); 
    ... 
    public synchronized boolean putIfAbsent(E x) { 
    boolean absent = !list.contains(x); 
    if (absent) 
    list.add(x); 
    return absent; 
    } 
} 

なぜこれが機能しないのかわかりません。なぜロックが間違っていますか?

リストを私用フィールドに変更した場合、このコードは正しくありませんか?

+0

私はあなたが何をしたいのか、何がうまくいかないのかという手がかりはありませんが、あなたは 'Set'を否定しているように見え、' List'を使ってそれを使いたいかもしれません。 – SomeJavaGuy

答えて

1

​​ロックをバイパスして、他のコードがlistに直接アクセスできるため、コードは機能しません(つまり、アクセスを確実に同期させません)。

privateにするとそれを防ぐことができます。

あなたがsynchronizedListを使用しているという事実は、それに関係する同期ロックがあなたのメソッドが使用しているものと同じであるが、そうでない場合には役に立ちません。

listを公開したい場合は、同じロック(つまりlist自体)で同期するようにメソッドを更新することができます。

このアプローチはdetailed in the JavaDoc for synchronizedListです。

関連する問題