4. Java IO: Pipes

想要查看此教程的目录请点击:Java IO教程目录贴地址


Java IO中,管道用来提供同一个jvm中的两个线程间的通信。所以管道也可以是数据的源或目的地。在不同的jvm(不同的进程)下,你不可以用管道去连接线程。Java的管道概念,不同于linux或unix的管道,linux或unix中,管道可以用来连接两个运行在不同地址空间的进程。(译者注:linux下的管道符为“ | ”,例如:ps -ef | grep java)。Java中,通讯部分必须在同一个进程下,可以使不同线程。

利用Java IO创建管道

用Java IO创建管道,已经有线程的类可以使用:PipedOutputStream和PipedInputStream。PipedInputStream可以用来连接PipedOutputStream。一个线程把数据写入到PipedOutputStream,可以被另一个线程创建的已经连接的PipedInputStream读取。

Java IO管道示例

这里提供一个简单的例子来演示如何去连接一个PipedInputStream到一个PipedOutputStream:

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

/**
 * 代码基于java8
 */
public class PipeExample {

    public static void main(String[] args) throws IOException {


        final PipedOutputStream pipedOutputStream = new PipedOutputStream();
        final PipedInputStream pipedInputStream = new PipedInputStream(pipedOutputStream);

        Runnable runnable1 = () -> {
            try {
                pipedOutputStream.write("hello kopshome".getBytes());
            } catch (IOException e) {
            }
        };

        Runnable runnable2 = () -> {
            try {
                int data = pipedInputStream.read();
                while (data != -1) {
                    System.out.println((char) data);
                    data = pipedInputStream.read();
                }
            } catch (IOException e) {
            }
        };

        new Thread(runnable1).start();
        new Thread(runnable2).start();
    }

}

除了利用构造方法外,你也可以用connect()方法来连接两个管道流。PipedInputStream和PipedOutputStream都有connect()方法。

管道和线程

记住这一点,当使用两个已连接的管道流时,流和线程应该是一一对应的关系。read()和write()方法是阻塞的方法,这意味着,如果你用同一个线程既读又写,那么就会造成这个线程的死锁。

管道的替代方案

在同一jvm中,线程间通讯有很多其他的办法。实际上线程间的交互,相比利用原始字节数据,更多的还是利用对象进行交互。当然了,如果你想利用原始数据进行线程间的交互,Java IO的管道流是一个不错的选择。

你可能感兴趣的:(4. Java IO: Pipes)