Java多线程问题--PipedReader和PipedWriter实现线程间通信

本文内容部分引自《Java多线程编程核心技术》,感谢作者!!!

代码地址:https://github.com/xianzhixianzhixian/thread.git

相关知识讲解

1、Java中提供了很多输入/输出流Stream,其中管道流(pipeStream)是一种特殊的流,用于在不同线程间直接传送数据。一个线程发送数据到输入管道,另一个线程从输入管道中读取数据。通过使用管道,可以实现不同线程间的通信,无需借助于类似临时文件之类的东西。

2、使用PipedReader和PipedWriter可以实现线程间通信:PipedReader用于从管道中读取字符流数据,PipedWriter用于向管道中写入字节符数据。

3、使用PipedReader中的connect(PipedWriter实例)或PipedWriter中的connect(PipedReader实例)来连接管道从而进行读写字符流数据,两者不可同时使用,否则会报java.io.IOException: Already connected错误。

代码示例

ReadData.java

/**
 * 使用PipedReader和PipedWriter实现线程间通信
 * @author: xianzhixianzhixian
 * @date: 2019-01-02 19:39
 */
public class ReadData {

    public void readMethod(PipedReader input){
        try {
            System.out.println("read:");
            char[] charArray = new char[20];
            int readLength = input.read(charArray);
            while (readLength != -1){
                String newData = new String(charArray, 0, readLength);
                System.out.print(newData);
                readLength = input.read(charArray);
            }
            System.out.println();
            input.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
/**
 * @author: xianzhixianzhixian
 * @date: 2019-01-02 20:02
 */
public class WriteData {

    public void writeMethod(PipedWriter out){
        try {
            System.out.println("write:");
            for (int i = 0; i < 300; i++) {
                String outData = "" + (i + 1);
                out.write(outData);
                System.out.print(outData);
            }
            System.out.println();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

ThreadRead.java

/**
 * 使用PipedReader和PipedWriter实现线程间通信
 * @author: xianzhixianzhixian
 * @date: 2019-01-02 19:45
 */
public class ThreadRead extends Thread {

    private ReadData read;
    private PipedReader input;

    public ThreadRead(ReadData read, PipedReader input) {
        this.read = read;
        this.input = input;
    }

    @Override
    public void run() {
        super.run();
        read.readMethod(input);
    }
}

ThreadWrite.java

/**
 * @author: xianzhixianzhixian
 * @date: 2019-01-02 19:43
 */
public class ThreadWrite extends Thread {

    private WriteData write;
    private PipedWriter out;

    public ThreadWrite(WriteData write, PipedWriter out) {
        this.write = write;
        this.out = out;
    }

    @Override
    public void run() {
        super.run();
        write.writeMethod(out);
    }
}

Run.java

/**
 * @author: xianzhixianzhixian
 * @date: 2019-01-02 19:46
 */
public class Run {

    public static void main(String[] args) {
        try {
            WriteData writeData = new WriteData();
            ReadData readData = new ReadData();

            PipedReader inputReader = new PipedReader();
            PipedWriter outputReader = new PipedWriter();

            //inputReader.connect(outputReader);
            outputReader.connect(inputReader);

            /**
             * 在代码中首先启动的是threadRead,由于当时没有数据被写入,所以线程阻塞在
             * int readLength=input.read(byteArray);直到有数据写入后,才继续向下运行。
             */
            ThreadRead threadRead = new ThreadRead(readData, inputReader);
            threadRead.start();

            Thread.sleep(2000);

            ThreadWrite threadWrite = new ThreadWrite(writeData, outputReader);
            threadWrite.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行结果:注意Run.java中先调用的是threadRead.start(),但是打印结果的时候还是先write后read的,因为虽然在代码中首先启动的是threadRead,由于当时没有数据被写入,所以线程阻塞在int readLength=input.read(charArray);直到有数据写入后,才继续向下运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值