通过管道 PipedInputStream和PipedOutputStream 可以实现不同线程之间的数据传输,使用很简单,先来看下简单的例子:
@Test
public void pipeTest() throws IOException, InterruptedException {
PipedOutputStream outputStream = new PipedOutputStream();
PipedInputStream inputStream = new PipedInputStream(outputStream);
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
outputStream.write("test".getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
}
try {
Thread.sleep(1000 * 5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
int len = inputStream.read();
while (len != -1) {
System.out.println((char) len);
len = inputStream.read();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
Thread.sleep(1000 * 100);
}
输出结果是 每隔5秒输出一个test
t
e
s
t
t
e
s
t
源码就简单说下:
通过PipedInputStream 的初始化或者connect 与PipedOutputStream 关联,当write时,其实就是调用input的方法,将write数据写入到input的buffer中
synchronized void receive(byte b[], int off, int len) throws IOException {
checkStateForReceive();
writeSide = Thread.currentThread();
int bytesToTransfer = len;
while (bytesToTransfer > 0) {
if (in == out)
awaitSpace();
int nextTransferAmount = 0;
if (out < in) {
nextTransferAmount = buffer.length - in;
} else if (in < out) {
if (in == -1) {
in = out = 0;
nextTransferAmount = buffer.length - in;
} else {
nextTransferAmount = out - in;
}
}
if (nextTransferAmount > bytesToTransfer)
nextTransferAmount = bytesToTransfer;
assert(nextTransferAmount > 0);
//将b数据赋给buffer
System.arraycopy(b, off, buffer, in, nextTransferAmount);
bytesToTransfer -= nextTransferAmount;
off += nextTransferAmount;
in += nextTransferAmount;
if (in >= buffer.length) {
in = 0;
}
}
}
可以看到加了synchronized,所以是线程安全的。然后input在read的时候,其实读的就是buffer里的内容。
需要注意的是 buffer默认容量大小是1024。