当前位置: 技术问答>java相关
多个线程用一个管道通信,不是异常就是无限等待,请指点。
来源: 互联网 发布时间:2015-09-25
本文导语: // 初学 java,练习多线程, // // 程序说明: 三个线程用一个管道通信,两个写入管道的线程 t 和 tt , // 主线程 m 读取管道。 // t 和 tt 中都没有关闭管道的写入...
// 初学 java,练习多线程,
//
// 程序说明: 三个线程用一个管道通信,两个写入管道的线程 t 和 tt ,
// 主线程 m 读取管道。
// t 和 tt 中都没有关闭管道的写入端。
//
// 运行结果: 当 t 和 tt 都结束之后,m 产生 IOException
//
// 请问: 1、why? 为什么不是 m 无限等待?
// 2、注释掉 语句1 和 语句2 ,结果似乎主线程无限阻塞,why?
// 3、我应该怎样关闭管道的写入端?
import java.io.*;
class t extends Thread {
public void run() {
try {
m.to_pipe.write(7); // 语句1
sleep(3*1000);
System.out.println("t finish");
} catch( Exception e) { e.printStackTrace(); }
}
}
class tt extends Thread {
public void run() {
try {
m.to_pipe.write(77); // 语句2
sleep(10*1000);
System.out.println("tt finish");
} catch( Exception e) { e.printStackTrace(); }
}
}
class m {
static PipedOutputStream to_pipe;
static PipedInputStream from_pipe;
public static void main( String[] args ) {
try {
to_pipe = new PipedOutputStream();
from_pipe = new PipedInputStream(to_pipe);
new t().start();
new tt().start();
for( int i; (i=from_pipe.read()) != -1; ) System.out.println( i );
} catch( Exception e ) { e.printStackTrace(); }
}
}
//
// 程序说明: 三个线程用一个管道通信,两个写入管道的线程 t 和 tt ,
// 主线程 m 读取管道。
// t 和 tt 中都没有关闭管道的写入端。
//
// 运行结果: 当 t 和 tt 都结束之后,m 产生 IOException
//
// 请问: 1、why? 为什么不是 m 无限等待?
// 2、注释掉 语句1 和 语句2 ,结果似乎主线程无限阻塞,why?
// 3、我应该怎样关闭管道的写入端?
import java.io.*;
class t extends Thread {
public void run() {
try {
m.to_pipe.write(7); // 语句1
sleep(3*1000);
System.out.println("t finish");
} catch( Exception e) { e.printStackTrace(); }
}
}
class tt extends Thread {
public void run() {
try {
m.to_pipe.write(77); // 语句2
sleep(10*1000);
System.out.println("tt finish");
} catch( Exception e) { e.printStackTrace(); }
}
}
class m {
static PipedOutputStream to_pipe;
static PipedInputStream from_pipe;
public static void main( String[] args ) {
try {
to_pipe = new PipedOutputStream();
from_pipe = new PipedInputStream(to_pipe);
new t().start();
new tt().start();
for( int i; (i=from_pipe.read()) != -1; ) System.out.println( i );
} catch( Exception e ) { e.printStackTrace(); }
}
}
|
看一下JDK Doc:
public int read()
throws IOExceptionReads the next byte of data from this piped input stream. The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown. If a thread was providing data bytes to the connected piped output stream, but the thread is no longer alive, then an IOException is thrown.
Specified by:
read in class InputStream
Returns:
the next byte of data, or -1 if the end of the stream is reached.
Throws:
IOException - if the pipe is broken.
这种情形说的很清楚
public int read()
throws IOExceptionReads the next byte of data from this piped input stream. The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown. If a thread was providing data bytes to the connected piped output stream, but the thread is no longer alive, then an IOException is thrown.
Specified by:
read in class InputStream
Returns:
the next byte of data, or -1 if the end of the stream is reached.
Throws:
IOException - if the pipe is broken.
这种情形说的很清楚
|
public void run() {
try {
M.to_pipe.write(77); // 语句2
sleep(10*1000);
System.out.println("tt finish");
M.to_pipe.close();
} catch( Exception e) { e.printStackTrace(); }
}
重写如上:加上"M.to_pipe.close();"
测试通过
try {
M.to_pipe.write(77); // 语句2
sleep(10*1000);
System.out.println("tt finish");
M.to_pipe.close();
} catch( Exception e) { e.printStackTrace(); }
}
重写如上:加上"M.to_pipe.close();"
测试通过
|
没有flush
|
主要原因是从名称上看PipedOutputStream() PipedInPutStream();的内部输入输出方向同正常的输入输出方向是相反的,而输入流的read()方法又一直等待实际作为前端输入流的管道输出流关闭所以当手动关闭时就可以了。