Considerations and Costs of Thread Pooling

Chapter 15 - Breaking Out of a Blocked I/O State

Java Thread Programming
Paul Hyde
  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


Java Thread Programming
Java Thread Programming
ISBN: 0672315858
EAN: 2147483647
Year: 2005
Pages: 149
Authors: Paul Hyde

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net