1 package psl;
2
3 import java.lang.management.ManagementFactory;
4 import java.util.ArrayList;
5 import java.util.Iterator;
6 import java.util.LinkedList;
7 import java.util.List;
8 import java.util.concurrent.ThreadFactory;
9
10 import javax.management.InstanceAlreadyExistsException;
11 import javax.management.InstanceNotFoundException;
12 import javax.management.MBeanRegistrationException;
13 import javax.management.MBeanServer;
14 import javax.management.MalformedObjectNameException;
15 import javax.management.NotCompliantMBeanException;
16 import javax.management.ObjectName;
17
18 import ensure.Ensure;
19
20
21
22
23 final class DispatcherThreadFactory implements ThreadFactory {
24
25
26
27 private int m_next_number;
28
29
30
31
32 private String m_name;
33
34
35
36
37 private ExceptionHandler m_exception_handler;
38
39
40
41
42 private List<DispatcherThread> m_created;
43
44
45
46
47 private ObjectName m_mx_name;
48
49
50
51
52 private boolean m_active;
53
54
55
56
57
58
59
60
61 private DispatcherThreadFactory(String name,
62 ExceptionHandler exception_handler) {
63 Ensure.not_null(name, "name == null");
64 Ensure.not_null(exception_handler, "exception_handler == null");
65
66 m_name = name;
67 m_next_number = 1;
68 m_exception_handler = exception_handler;
69 m_created = new LinkedList<>();
70 m_active = true;
71
72 try {
73 m_mx_name = object_name(m_name);
74 DispatcherThreadFactoryMXBeanImpl mx =
75 new DispatcherThreadFactoryMXBeanImpl(this);
76 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
77 mbs.registerMBean(mx, m_mx_name);
78 } catch (NotCompliantMBeanException | MBeanRegistrationException
79 | InstanceAlreadyExistsException e) {
80 Ensure.never_thrown(e);
81 }
82 }
83
84
85
86
87 synchronized void shutdown() {
88 Ensure.is_true(m_active, "m_active == false");
89
90 m_active = false;
91 m_created.clear();
92
93 try {
94 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
95 mbs.unregisterMBean(m_mx_name);
96 } catch (InstanceNotFoundException | MBeanRegistrationException e) {
97 Ensure.never_thrown(e);
98 }
99 }
100
101
102
103
104
105
106 public static ObjectName object_name(String factory_name) {
107 Ensure.not_null(factory_name, "factory_name == null");
108
109 try {
110 return new ObjectName(DispatcherThreadFactory.class.getName()
111 + ":name=" + factory_name + ",info=factory");
112 } catch (MalformedObjectNameException e) {
113 return Ensure.never_thrown(e);
114 }
115 }
116
117
118
119
120
121
122
123
124 public static DispatcherThreadFactory make(String name,
125 ExceptionHandler exception_handler) {
126 Ensure.not_null(name, "name == null");
127 Ensure.not_null(exception_handler, "exception_handler == null");
128
129 DispatcherThreadFactory factory = new DispatcherThreadFactory(name,
130 exception_handler);
131 return factory;
132 }
133
134 @Override
135 public synchronized Thread newThread(Runnable r) {
136 Ensure.not_null(r, "r == null");
137 Ensure.is_true(m_active, "m_active == false");
138
139 DispatcherThread t = DispatcherThread.make(r, m_name,
140 m_next_number, m_exception_handler);
141 m_next_number++;
142 clear_terminated();
143 m_created.add(t);
144 return t;
145 }
146
147
148
149
150
151 public synchronized List<DispatcherThread> threads() {
152 Ensure.is_true(m_active, "m_active == false");
153
154 clear_terminated();
155 List<DispatcherThread> all = new ArrayList<>(m_created);
156 return all;
157 }
158
159
160
161
162 private void clear_terminated() {
163 Iterator<DispatcherThread> it = m_created.iterator();
164 while (it.hasNext()) {
165 DispatcherThread dt = it.next();
166 if (dt.done()) {
167 it.remove();
168 }
169 }
170 }
171
172
173
174
175
176 public String name() {
177 return m_name;
178 }
179
180
181
182
183
184 public synchronized int thread_count() {
185 clear_terminated();
186 return m_created.size();
187 }
188 }