Browse Source

ListenerList is now perfectly, magically thread safe

There's no longer any need to synchronise when adding or
iterating to a listener list.

Change-Id: Ie39fbd92650bebffb13524e6054b187c3699833e
Reviewed-on: http://gerrit.dmdirc.com/1124
Reviewed-by: Gregory Holmes <greg@dmdirc.com>
Automatic-Compile: Chris Smith <chris@dmdirc.com>
tags/0.6.4
Chris Smith 14 years ago
parent
commit
5b2abacfa5
1 changed files with 23 additions and 12 deletions
  1. 23
    12
      src/com/dmdirc/util/ListenerList.java

+ 23
- 12
src/com/dmdirc/util/ListenerList.java View File

22
 
22
 
23
 package com.dmdirc.util;
23
 package com.dmdirc.util;
24
 
24
 
25
-import java.util.List;
25
+import java.util.Collection;
26
+import java.util.HashMap;
27
+import java.util.Map;
28
+import java.util.concurrent.ConcurrentSkipListSet;
26
 
29
 
27
 /**
30
 /**
28
  * Represents a list of event listeners, similar to EventListenerList, but
31
  * Represents a list of event listeners, similar to EventListenerList, but
33
 public class ListenerList {
36
 public class ListenerList {
34
     
37
     
35
     /** The map of class->listener or string->listener that we're using. */
38
     /** The map of class->listener or string->listener that we're using. */
36
-    private final MapList<Object, Object> listeners
37
-            = new MapList<Object, Object>();
39
+    private final Map<Object, Collection<Object>> listeners
40
+            = new HashMap<Object, Collection<Object>>();
38
     
41
     
39
     /**
42
     /**
40
      * Creates a new instance of ListenerList.
43
      * Creates a new instance of ListenerList.
50
      * @param listener The listener to be added
53
      * @param listener The listener to be added
51
      */
54
      */
52
     public <T> void add(final Class<T> listenerType, final T listener) {
55
     public <T> void add(final Class<T> listenerType, final T listener) {
53
-        listeners.add(listenerType, listener);
56
+        if (!listeners.containsKey(listenerType)) {
57
+            listeners.put(listenerType, new ConcurrentSkipListSet<Object>());
58
+        }
59
+
60
+        listeners.get(listenerType).add(listener);
54
     }
61
     }
55
     
62
     
56
     /**
63
     /**
60
      * @param listener The listener to be added
67
      * @param listener The listener to be added
61
      */
68
      */
62
     public void add(final String listenerType, final Object listener) {
69
     public void add(final String listenerType, final Object listener) {
63
-        listeners.add(listenerType, listener);
70
+        if (!listeners.containsKey(listenerType)) {
71
+            listeners.put(listenerType, new ConcurrentSkipListSet<Object>());
72
+        }
73
+
74
+        listeners.get(listenerType).add(listener);
64
     }
75
     }
65
     
76
     
66
     /**
77
     /**
71
      * @param listener The listener to be removed
82
      * @param listener The listener to be removed
72
      */
83
      */
73
     public <T> void remove(final Class<T> listenerType, final T listener) {
84
     public <T> void remove(final Class<T> listenerType, final T listener) {
74
-        listeners.remove(listenerType, listener);
85
+        listeners.get(listenerType).remove(listener);
75
     }
86
     }
76
     
87
     
77
     /**
88
     /**
83
      * @param listener The listener to be removed
94
      * @param listener The listener to be removed
84
      */
95
      */
85
     public void remove(final String listenerType, final Object listener) {
96
     public void remove(final String listenerType, final Object listener) {
86
-        listeners.remove(listenerType, listener);
97
+        listeners.get(listenerType).remove(listener);
87
     }
98
     }
88
     
99
     
89
     /**
100
     /**
93
      * @return A list of listeners for the specified type
104
      * @return A list of listeners for the specified type
94
      */
105
      */
95
     @SuppressWarnings("unchecked")
106
     @SuppressWarnings("unchecked")
96
-    public <T> List<T> get(final Class<T> listenerType) {
107
+    public <T> Collection<T> get(final Class<T> listenerType) {
97
         if (listeners.containsKey(listenerType)) {
108
         if (listeners.containsKey(listenerType)) {
98
-            return (List<T>) listeners.get(listenerType);
109
+            return (Collection<T>) listeners.get(listenerType);
99
         } else {
110
         } else {
100
-            return new WeakList<T>();
111
+            return new ConcurrentSkipListSet<T>();
101
         }
112
         }
102
     }
113
     }
103
     
114
     
107
      * @param listenerType The type of listener to be retrieved
118
      * @param listenerType The type of listener to be retrieved
108
      * @return A list of listeners for the specified type
119
      * @return A list of listeners for the specified type
109
      */
120
      */
110
-    public List<Object> get(final String listenerType) {
121
+    public Collection<Object> get(final String listenerType) {
111
         if (listeners.containsKey(listenerType)) {
122
         if (listeners.containsKey(listenerType)) {
112
             return listeners.get(listenerType);
123
             return listeners.get(listenerType);
113
         } else {
124
         } else {
114
-            return new WeakList<Object>();
125
+            return new ConcurrentSkipListSet<Object>();
115
         }
126
         }
116
     }
127
     }
117
 
128
 

Loading…
Cancel
Save