| ||||
Copyright 1999 Sams Publishing |
|
Peering Inside Using SureStopVerbose |
The class SureStopVerbose (see Listing 16.2) is identical to SureStop except that it provides some detailed output. A new static method print() has been added (lines 198206) to assist in printing messages. Throughout the code, calls to print() are used to show the internal settings. Other than that, SureStopVerbose works exactly like SureStop . SureStopVerbose is used by the demonstration code in the next section to reveal the classs inner workings. When SureStopVerbose is compiled, the compiler issues an expected warning because the deprecated stop() method is used. |
Listing 16.2 SureStopVerbose.javaChatty SureStop that Shows Inner Processing |
1: import java.util.*; |
2: |
3: public class SureStopVerbose extends Object { |
4: // nested internal class for stop request entries |
5: private static class Entry extends Object { |
6: private Thread thread; |
7: private long stopTime; |
8: |
9: private Entry(Thread t, long stop) { |
10: thread = t; |
11: stopTime = stop; |
12: } |
13: } |
14: |
15: // static reference to the singleton instance |
16: private static SureStopVerbose ss; |
17: |
18: static { |
19: // When class is loaded, create exactly one instance |
20: // using the private constructor. |
21: ss = new SureStopVerbose(); |
22: print(SureStopVerbose instance created.); |
23: } |
24: |
25: private List stopList; |
26: private List pendingList; |
27: private Thread internalThread; |
28: |
29: private SureStopVerbose() { |
30: // using a linked list for fast deletions |
31: stopList = new LinkedList(); |
32: |
33: // Enough initial capacity for 20 pending additions, |
34: // will grow automatically if necessary to keep |
35: // ensureStop() from blocking. |
36: pendingList = new ArrayList(20); |
37: |
38: Runnable r = new Runnable() { |
39: public void run() { |
40: try { |
41: runWork(); |
42: } catch (Exception x) { |
43: // in case ANY exception slips through |
44: x.printStackTrace(); |
45: } |
46: } |
47: }; |
48: |
49: internalThread = new Thread(r); |
50: internalThread.setDaemon(true); // no need to run alone |
51: internalThread.setPriority(Thread.MAX_PRIORITY); // high |
52: internalThread.start(); |
53: } |
54: |
55: private void runWork() { |
56: try { |
57: while (true) { |
58: // Since this is a super-high priority thread, |
59: // be sure to give other threads a chance to |
60: // run each time through in case the wait on |
61: // pendingList is very short. |
62: print(about to sleep for 0.5 seconds); |
63: Thread.sleep(500); |
64: print(done with sleep for 0.5 seconds); |
65: |
66: long sleepTime = checkStopList(); |
67: print(back from checkStopList(), sleepTime= + |
68: sleepTime); |
69: |
70: synchronized (pendingList) { |
71: if (pendingList. size () < 1) { |
72: print(about to wait on pendingList + |
73: for + sleepTime + ms); |
74: long start = System.currentTimeMillis(); |
75: pendingList.wait(sleepTime); |
76: long elapsedTime = |
77: System.currentTimeMillis() - start; |
78: print(waited on pendingList for + |
79: elapsedTime + ms); |
80: } |
81: |
82: |
83: if (pendingList.size() > 0) { |
84: // copy into stopList and then remove |
85: // from pendingList. |
86: print(copying + pendingList.size() + |
87: elements from pendingList to + |
88: stopList); |
89: int oldSize = stopList.size(); |
90: stopList.addAll(pendingList); |
91: pendingList.clear(); |
92: int newSize = stopList.size(); |
93: print(pendingList.size()= + |
94: pendingList.size() + |
95: , stopList grew by + |
96: (newSize - oldSize)); |
97: } |
98: } |
99: } // while |
100: } catch (InterruptedException x) { |
101: // ignore |
102: } catch (Exception x) { |
103: // Never expect this, but print a trace in case |
104: // it happens. |
105: x.printStackTrace(); |
106: } |
107: } |
108: |
Listing 16.2 Continued |
109: private long checkStopList() { |
110: print(entering checkStopList() - stopList.size()= + |
111: stopList.size()); |
112: long currTime = System.currentTimeMillis(); |
113: long minTime = Long.MAX_VALUE; |
114: |
115: Iterator iter = stopList.iterator(); |
116: while (iter.hasNext()) { |
117: Entry entry = (Entry) iter.next(); |
118: |
119: if (entry.thread.isAlive()) { |
120: print(thread is alive - + |
121: entry.thread.getName()); |
122: if (entry.stopTime < currTime) { |
123: // timed out, stop it abruptly right now |
124: print(timed out, stopping - + |
125: entry.thread.getName()); |
126: try { |
127: entry.thread.stop(); |
128: } catch (SecurityException x) { |
129: // Catch this here so that other |
130: // operations are not disrupted. Warn |
131: // that thread could not be stopped . |
132: System.err.println( |
133: SureStop was not permitted to + |
134: stop thread= + entry.thread); |
135: x.printStackTrace(); |
136: } |
137: |
138: // Since its stopped, remove it |
139: // from stopList. |
140: iter.remove(); |
141: } else { |
142: // Not yet expired , check to see if this |
143: // is the new minimum. |
144: minTime = Math.min(entry.stopTime, minTime); |
145: print(new minTime= + minTime); |
146: } |
147: } else { |
148: print(thread died on its own - + |
149: entry.thread.getName()); |
150: // Thread died on its own, remove it from |
151: // stopList. |
152: iter.remove(); |
153: } // if alive |
154: } // while |
155: |
156: long sleepTime = minTime - System.currentTimeMillis(); |
157: |
158: // ensure that it is a least a little bit of time |
159: sleepTime = Math.max(50, sleepTime); |
160: |
161: print(leaving checkStopList() - stopList.size()= + |
162: stopList.size()); |
163: return sleepTime; |
164: } |
165: |
166: private void addEntry(Entry entry) { |
167: synchronized (pendingList) { |
168: pendingList.add(entry); |
169: |
170: // no need for notifyAll(), one waiter |
171: pendingList.notify(); |
172: print(added entry to pendingList, name = + |
173: entry.thread.getName() + |
174: , stopTime= + entry.stopTime + , in + |
175: (entry.stopTime - System.currentTimeMillis()) + |
176: ms); |
177: } |
178: } |
179: |
180: public static void ensureStop(Thread t, long msGracePeriod) { |
181: print(entering ensureStop() - name= + t.getName() + |
182: , msGracePeriod= + msGracePeriod); |
183: |
184: if (!t.isAlive()) { |
185: // thread is already stopped, return right away |
186: print(already stopped, not added to list - + |
187: t.getName()); |
188: return; |
189: } |
190: |
191: long stopTime = |
192: System.currentTimeMillis() + msGracePeriod; |
193: Entry entry = new Entry(t, stopTime); |
194: ss.addEntry(entry); |
195: print(leaving ensureStop() - name= + t.getName()); |
196: } |
197: |
198: private static void print(String msg) { |
199: Thread t = Thread.currentThread(); |
200: String name = t.getName(); |
201: if (t == ss.internalThread) { |
202: name = SureStopThread; |
203: } |
204: |
205: System.out.println(name + : + msg); |
206: } |
207: } |
| |||
Toc |