2016-04-12 2 views
11

小さなクラスのオブザーバパターン(リスナー)を自分のクラスの1つに導入したいだけで、ベストプラクティスのアプローチを使いたいと思います。Javaのリスナーの正しい(そして最良の)コレクションのタイプ

マイリスナーインタフェース:

public interface ExpansionListener { 
    void expanded(); 
    void collapsed(); 
} 

したがって、私はリスナー

private List listener; // What kind of list should I take? 

と二つの方法addListener(ExpansionListener l)removeListener(ExpansionListener l)のリストを維持したいです。

今、私の質問:どのようなリストを取る必要がありますか? CopyOnWriteArrayListのような並行リストを使うことを考えましたが、EventListenerListも存在することがわかりました。 Javaのリスナーリストのベストプラクティスアプローチは何ですか?

+0

EventListenerListをあなたが唯一のリスナーのようなものを許可したい場合、私は、 '開始のための'リストを使用すると思います良い候補 – Sanjeev

+2

のようです。それでは、おそらく 'CopyOnWriteArrayList'を使うでしょう。なぜなら、リスナーへの変更は非常に少ないかもしれませんが、複数のスレッド(あなたのアーキテクチャーについての仮定)だけで書き込みが並行して起こるからです。 – Thomas

+0

オブジェクトが同じ型の複数のリスナーを持つのを防ぐには、 'Set'がより適切です。 – Titus

答えて

9

CopyOnWriteArrayListはスレッドセーフです。すべてのSwingコンポーネントがスレッドセーフではありません。

注:Java 8より前では、このコレクションを反復するとゴミが生成されますが、Java 8ではIteratorをエスケープ解析でスタックに配置できます。

final List<EventListener> listeners = new CopyOnWriteArrayList<>(); 

if (!listeners.contains(listener)) 
    listeners.add(listener); 

リスナーの重複登録をスレッドセーフな方法で無視したい場合は、Setを使用することをお勧めします。 CopyOnWriteArraySetaddcontainsをやって、その後はアトミックでない場合addは、アトミックであるという利点を有しているものの

final Set<EventListener> listeners = new CopyOnWriteArraySet<>(); 

listeners.add(listener); 

パフォーマンスは、ほとんど同じになります。

EDIT:@HulkはCopyOnWriteArrayList.addIfAbsentを使用できると示唆していますが、このメソッドはListでは使用できません。

final CopyOnWriteArrayList<EventListener> listeners = new CopyOnWriteArrayList<>(); 

listeners.addIfAbsent(listener); 
+0

@Hulk 'Copy'WriteArrayList'は' List'で利用できません –

関連する問題