KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > service > impl > ThreadEventNotifierImpl


1 // Copyright 2004, 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.hivemind.service.impl;
16
17 import java.util.Iterator JavaDoc;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.apache.hivemind.service.ThreadCleanupListener;
22 import org.apache.hivemind.service.ThreadEventNotifier;
23 import org.apache.hivemind.util.Defense;
24 import org.apache.hivemind.util.EventListenerList;
25
26 /**
27  * Implementation of {@link org.apache.hivemind.service.ThreadEventNotifier}, available as service
28  * <code>hivemind.ThreadEventNotifier</code>.
29  *
30  * @author Howard Lewis Ship
31  */

32 public class ThreadEventNotifierImpl implements ThreadEventNotifier
33 {
34     private static final Log DEFAULT_LOG = LogFactory.getLog(ThreadEventNotifier.class);
35
36     private final Log _log;
37
38     private final ThreadLocal JavaDoc _storage = new ThreadLocal JavaDoc();
39
40     public ThreadEventNotifierImpl()
41     {
42         this(DEFAULT_LOG);
43     }
44
45     public ThreadEventNotifierImpl(Log log)
46     {
47         Defense.notNull(log, "log");
48
49         _log = log;
50     }
51
52     public void addThreadCleanupListener(ThreadCleanupListener listener)
53     {
54         EventListenerList list = (EventListenerList) _storage.get();
55
56         if (list == null)
57         {
58             list = new EventListenerList();
59             _storage.set(list);
60         }
61
62         list.addListener(listener);
63     }
64
65     public void removeThreadCleanupListener(ThreadCleanupListener listener)
66     {
67         EventListenerList list = (EventListenerList) _storage.get();
68
69         if (list != null)
70             list.removeListener(listener);
71     }
72
73     public void fireThreadCleanup()
74     {
75         // Here's where we need the CursorableLinkedList since listeners
76
// are free to unregister as listeners from threadDidCleanup() and
77
// we need to avoid concurrent modification errors.
78

79         EventListenerList list = (EventListenerList) _storage.get();
80
81         if (list == null)
82             return;
83
84         Iterator JavaDoc i = list.getListeners();
85
86         // Discard the list of listeners as early as possible to ensure that
87
// they can in no way be retained, even if this thread aborts abnormally.
88

89         _storage.set(null);
90
91         while (i.hasNext())
92         {
93             ThreadCleanupListener listener = (ThreadCleanupListener) i.next();
94
95             // Each listener may decide to remove itself; that's OK,
96
// EventListenerList handles that kind of concurrent modification
97
// well.
98

99             try
100             {
101                 listener.threadDidCleanup();
102             }
103             catch (RuntimeException JavaDoc ex)
104             {
105                 _log.warn(ServiceMessages.threadCleanupException(ex), ex);
106             }
107         }
108     }
109
110 }
111
Popular Tags