2017-03-11 9 views
1
List synchronizedList=new Collections.synchronizedList(new ArrayList()); 
synchronized (synchronizedList) { 
    if (synchronizedList.size() > 0) { 
     System.out.println(synchronizedList.get(0)); 
    } 
} 

上記のコードは、最初にチェックしてから実行します。チェックなしでCopyOnwriteArrayListを使用してこの機能を実現できます。同期されたリストを確認してから処理する方法はありますか?

+1

同期リストを使用するときに同期チェックが必要なのはなぜですか?さらに重要なのは、あなたが解決しようとする問題は何ですか? – GhostCat

+0

ここで行っていることがすべて読んでいるときに、同期が必要なのはなぜですか? –

+0

COWALには 'getIfPresent'メソッドはありません。なぜ現在のコードを変更したいのですか? – assylias

答えて

1

一言で言えば、 CopyOnWriteArrayListでも、要素がリストに存在するかどうかをチェックし、MapのインターフェイスcomputeIfPresentのようなコードを実行するためのアトミックな操作は提供されません。長いストーリーを短くするには、質問のスニペットのように、自分でロジックを実装する必要があります。

1

これは同期せずに行うことが安全である:イテレータだったときに返された反復子がリストの状態のスナップショットを提供

// given CopyOnWriteArrayList<T> list 
Iterator<T> iterator = list.iterator(); 
if (iterator.hasNext()) { 
    return iterator.next(); 
} 

安全性がCopyOnWriteArrayList.iteratorのこの性質によって保証されています構築された。イテレータをトラバースする際に同期は必要ありません。

だから、

リストは、(そのことについて、またはその他)、あなたはイテレータを得た時点で 最初の項目は空でなかった場合、 はまだそこになり、アクセスし、 他のスレッドを持っていることがあっても一覧にはremoveまたはclearと呼ばれます。 (これは、このクラスのコピーオンライトのおかげで動作します)

関連する問題