| ||||
Copyright 1999 Sams Publishing |
|
Using BufferedThreadedInputStream for Interruptible I/O |
Now its time to combine the techniques presented so far. CalcServerTwo (see Listing 15.9) has been slightly modified to work with CalcWorkerTwo . CalcWorkerTwo (see Listing 15.10 ) now uses a BufferedThreadedInputStream as an inline filter so that when it is blocked trying to read() , it will respond to an interrupt. |
Listing 15.9 CalcServerTwo.javaModified to Work with CalcWorkerTwo |
1: import java.io.*; |
2: import java.net.*; |
3: import java.util.*; |
4: |
5: public class CalcServerTwo extends Object { |
6: private ServerSocket ss; |
7: private List workerList; |
8: |
9: private Thread internalThread; |
10: private volatile boolean noStopRequested; |
11: |
12: public CalcServerTwo (int port) throws IOException { |
13: ss = new ServerSocket(port); |
14: workerList = new LinkedList(); |
15: |
16: noStopRequested = true; |
17: Runnable r = new Runnable() { |
18: public void run() { |
19: try { |
20: runWork(); |
21: } catch (Exception x) { |
22: // in case ANY exception slips through |
23: x.printStackTrace(); |
24: } |
25: } |
26: }; |
27: |
28: internalThread = new Thread(r); |
29: internalThread.start(); |
30: } |
31: |
32: private void runWork() { |
33: System.out.println( |
34: in CalcServer - ready to accept connections); |
35: |
36: while (noStopRequested) { |
37: try { |
38: System.out.println( |
39: in CalcServer - about to block + |
40: waiting for a new connection); |
41: Socket sock = ss.accept(); |
42: System.out.println( |
43: in CalcServer - received new connection); |
44: workerList.add(new CalcWorkerTwo (sock)); |
45: } catch (IOException iox) { |
46: if (noStopRequested) { |
47: iox.printStackTrace(); |
48: } |
49: } |
50: } |
51: |
52: // stop all the workers that were created |
53: System.out.println(in CalcServer - putting in a + |
54: stop request to all the workers); |
55: Iterator iter = workerList.iterator(); |
56: while (iter.hasNext()) { |
57: CalcWorkerTwo worker = ( CalcWorkerTwo ) iter. next (); |
58: worker.stopRequest(); |
59: } |
60: |
61: System.out.println(in CalcServer - leaving runWork()); |
62: } |
63: |
64: public void stopRequest() { |
65: System.out.println( |
66: in CalcServer - entering stopRequest()); |
67: noStopRequested = false; |
68: internalThread.interrupt(); |
69: |
70: if (ss != null) { |
71: try { |
72: ss.close(); |
73: } catch (IOException x) { |
74: // ignore |
75: } finally { |
76: ss = null; |
77: } |
78: } |
79: } |
80: |
81: public boolean isAlive() { |
82: return internalThread.isAlive(); |
83: } |
84: |
85: public static void main(String[] args) { |
86: int port = 2001; |
87: |
88: try { |
89: CalcServerTwo server = new CalcServerTwo (port); |
90: Thread.sleep(15000); |
91: server.stopRequest(); |
92: } catch (IOException x) { |
93: x.printStackTrace(); |
94: } catch (InterruptedException x) { |
95: // ignore |
96: } |
97: } |
98: } |
Listing 15.10 CalcWorkerTwo.javaUsing BufferedThreadedInputStream |
1: import java.io.*; |
2: import java.net.*; |
3: |
4: public class CalcWorkerTwo extends Object { |
5: private DataInputStream dataIn; |
6: private DataOutputStream dataOut; |
7: |
8: private Thread internalThread; |
9: private volatile boolean noStopRequested; |
10: |
11: public CalcWorkerTwo(Socket sock) throws IOException { |
12: dataIn = new DataInputStream( |
13: new BufferedThreadedInputStream( |
14: sock.getInputStream())); |
15: dataOut = new DataOutputStream( |
16: new BufferedOutputStream( |
17: sock.getOutputStream())); |
18: |
19: noStopRequested = true; |
20: Runnable r = new Runnable() { |
21: public void run() { |
22: try { |
23: runWork(); |
24: } catch (Exception x) { |
25: // in case ANY exception slips through |
26: x.printStackTrace(); |
27: } |
28: } |
29: }; |
30: |
31: internalThread = new Thread(r); |
32: internalThread.start(); |
33: } |
34: |
35: private void runWork() { |
36: while (noStopRequested) { |
37: try { |
38: System.out.println(in CalcWorker - about to + |
39: block waiting to read a double); |
40: double val = dataIn.readDouble(); |
41: System.out.println( |
42: in CalcWorker - read a double!); |
43: dataOut.writeDouble(Math.sqrt(val)); |
44: dataOut.flush(); |
45: } catch (InterruptedIOException iiox) { |
46: System.out.println(in CalcWorker - blocked + |
47: read was interrupted !!!); |
48: } catch (IOException x) { |
49: if (noStopRequested) { |
50: x.printStackTrace(); |
51: stopRequest(); |
52: } |
53: } |
54: } |
55: |
56: // In real-world code, be sure to close other streams |
57: // and the socket as part of the clean-up. Omitted here |
58: // for brevity. |
59: |
60: System.out.println(in CalcWorker - leaving runWork()); |
61: } |
62: |
63: public void stopRequest() { |
64: System.out.println( |
65: in CalcWorker - entering stopRequest()); |
66: noStopRequested = false; |
67: internalThread.interrupt(); |
68: System.out.println( |
69: in CalcWorker - leaving stopRequest()); |
70: } |
71: |
72: public boolean isAlive() { |
73: return internalThread.isAlive(); |
74: } |
75: } |
CalcWorkerTwo has been modified to take advantage of the interruptible I/O of BufferedThreadedInputStream (line 13). The InterruptedIOException has been caught in this code simply to print a message (lines 4547) but can be ignored. The stopRequest() method (lines 6370) has been simplified back down to the self-running object templateonly an interrupt() is necessary to unblock a read() . |
The same CalcClient code can be used with the new CalcServerTwo and CalcWorkerTwo . Listing 15.11 shows possible output from CalcServerTwo . Your output should match very closely with only a message or two swapped. |
Listing 15.11 Possible Output from CalcServerTwo |
1: in CalcServer - ready to accept connections |
2: in CalcServer - about to block waiting for a new connection |
3: in CalcServer - received new connection |
4: in CalcServer - about to block waiting for a new connection |
5: in CalcWorker - about to block waiting to read a double |
6: in CalcWorker - read a double! |
7: in CalcWorker - about to block waiting to read a double |
8: in CalcServer - entering stopRequest() |
9: in CalcServer - putting in a stop request to all the workers |
10: in CalcWorker - entering stopRequest() |
11: in CalcWorker - leaving stopRequest() |
12: in CalcWorker - blocked read was interrupted!!! |
13: in CalcServer - leaving runWork() |
14: in CalcWorker - leaving runWork() |
The main difference in the output from what was seen before is line 12. Here, a message is printed confirming that an InterruptedIOException was thrown when the blocked thread was interrupted. |
| |||
Toc |