Name: bsC130419 Date: 07/13/2001
happens in many JREs, including Apple's MRJ 2.2/Mac, and Sun's JRE 1.3/Linux
/* BufferedInputStream blocking problem
Problem:
BufferedInputStream blocks until enough bytes are available to fill its
internal buffer, even if fewer bytes have been requested. In a client/
server application, this can cause a deadlock: the client waits forever
for the buffer to be filled, while the server waits forever for the
client to finish processing the response and issue another request.
The output of this test program should look like this:
$ java BisBugTest
read 0x1020304 in 0 milliseconds.
read 0x1020304 in 1004 milliseconds.
read 0x1020304 in 1010 milliseconds.
read 0x1020304 in 1010 milliseconds.
read 0x1020304 in 1010 milliseconds.
Instead, it looks like this:
$ java BisBugTest
read 0x1020304 in 515964 milliseconds.
read 0x1020304 in 0 milliseconds.
read 0x1020304 in 0 milliseconds.
read 0x1020304 in 0 milliseconds.
read 0x1020304 in 0 milliseconds.
In this test run, the first read was delayed by 516 seconds (about 9 minutes).
*/
import java.io.*;
public class BisBugTest {
public static void main (String args []) {
try {
// This creates a stream that sends 1,2,3,4; waits 1 second; repeats
InputStream r = new RepeatStream (new byte [] {1, 2, 3, 4}, 1000);
DataInputStream d = new DataInputStream (new BufferedInputStream
(r));
// DataInputStream d = new DataInputStream (r); // this way it works OK
while (true) {
long start = System.currentTimeMillis ();
int i = d.readInt ();
long end = System.currentTimeMillis ();
System.out.print ("read 0x" + Integer.toHexString (i));
System.out.println (" in " + (end - start) + " milliseconds.");
}
} catch (Exception e) {
e.printStackTrace ();
}
}
// This input stream emulates a server that sends a series of bytes, waits a
// while, sends the same series of bytes again, waits again, ad infinitum...
public static class RepeatStream extends InputStream {
private int sleepMillis;
private byte contents [];
private int index = 0;
public RepeatStream (byte contents [], int sleepMillis) {
this.contents = contents;
this.sleepMillis = sleepMillis;
}
public int available () {
return contents.length - index;
}
public int read ()
throws IOException {
if (index == contents.length) {
sleep (sleepMillis);
index = 0;
}
return contents [index++] & 0xff;
}
private static void sleep (int timeout)
throws IOException {
try {
Thread.sleep (timeout);
} catch (InterruptedException e) {
throw new InterruptedIOException (e.getMessage ());
}
}
}
}
(Review ID: 126530)
======================================================================
happens in many JREs, including Apple's MRJ 2.2/Mac, and Sun's JRE 1.3/Linux
/* BufferedInputStream blocking problem
Problem:
BufferedInputStream blocks until enough bytes are available to fill its
internal buffer, even if fewer bytes have been requested. In a client/
server application, this can cause a deadlock: the client waits forever
for the buffer to be filled, while the server waits forever for the
client to finish processing the response and issue another request.
The output of this test program should look like this:
$ java BisBugTest
read 0x1020304 in 0 milliseconds.
read 0x1020304 in 1004 milliseconds.
read 0x1020304 in 1010 milliseconds.
read 0x1020304 in 1010 milliseconds.
read 0x1020304 in 1010 milliseconds.
Instead, it looks like this:
$ java BisBugTest
read 0x1020304 in 515964 milliseconds.
read 0x1020304 in 0 milliseconds.
read 0x1020304 in 0 milliseconds.
read 0x1020304 in 0 milliseconds.
read 0x1020304 in 0 milliseconds.
In this test run, the first read was delayed by 516 seconds (about 9 minutes).
*/
import java.io.*;
public class BisBugTest {
public static void main (String args []) {
try {
// This creates a stream that sends 1,2,3,4; waits 1 second; repeats
InputStream r = new RepeatStream (new byte [] {1, 2, 3, 4}, 1000);
DataInputStream d = new DataInputStream (new BufferedInputStream
(r));
// DataInputStream d = new DataInputStream (r); // this way it works OK
while (true) {
long start = System.currentTimeMillis ();
int i = d.readInt ();
long end = System.currentTimeMillis ();
System.out.print ("read 0x" + Integer.toHexString (i));
System.out.println (" in " + (end - start) + " milliseconds.");
}
} catch (Exception e) {
e.printStackTrace ();
}
}
// This input stream emulates a server that sends a series of bytes, waits a
// while, sends the same series of bytes again, waits again, ad infinitum...
public static class RepeatStream extends InputStream {
private int sleepMillis;
private byte contents [];
private int index = 0;
public RepeatStream (byte contents [], int sleepMillis) {
this.contents = contents;
this.sleepMillis = sleepMillis;
}
public int available () {
return contents.length - index;
}
public int read ()
throws IOException {
if (index == contents.length) {
sleep (sleepMillis);
index = 0;
}
return contents [index++] & 0xff;
}
private static void sleep (int timeout)
throws IOException {
try {
Thread.sleep (timeout);
} catch (InterruptedException e) {
throw new InterruptedIOException (e.getMessage ());
}
}
}
}
(Review ID: 126530)
======================================================================
- relates to
-
JDK-6192696 BufferedInputStream.read(byte[], int, int) can block if the entire buffer can't be filled
- Closed