有2个线程,一个是发送者,一个是接收者,发送者发送完后接收者开始接收,代码如下:
Sender.java:
package com.alibaba.stream.thread; import java.io.IOException; import java.io.PipedOutputStream; public class Sender implements Runnable { private PipedOutputStream out = new PipedOutputStream(); private String content = ""; private Receiver rcv; public Sender(String content, Receiver rcv) { super(); this.content = content; this.rcv = rcv; } public Sender() { } /** * @param content * the content to set */ public void setContent(String content) { this.content = content; } /** * @param rcv * the rcv to set */ public void setRcv(Receiver rcv) { this.rcv = rcv; } @Override public void run() { try { out.write(content.getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } // 通知接收者可以接收了 synchronized (this) { rcv.setFinished(true); } } /** * @return the out */ public PipedOutputStream getOut() { return out; } }
Receiver.java:
package com.alibaba.stream.thread; import java.io.IOException; import java.io.PipedInputStream; public class Receiver implements Runnable { // 标志域,用于检查发送者是否已发送完数据 private volatile boolean finished = false; private PipedInputStream in = new PipedInputStream(); // 存储接收到的数据 private StringBuilder content = new StringBuilder(); @Override public void run() { // 不断睡眠,直至发送者已经写完数据 while (!finished) { try { Thread.sleep(1000); System.out.println("sleeping...."); } catch (InterruptedException e) { e.printStackTrace(); } } try { byte[] buff = new byte[1024]; int len; while ((len = in.read(buff)) != -1) { content.append(new String(buff, 0, len)); } } catch (IOException e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } showContent(); } // 显示接收到的数据 private void showContent() { // 可以考虑输出到文件 System.out.println("接收到的内容:\n" + content); } /** * @return the finished */ public boolean isFinished() { return finished; } /** * @param finished * the finished to set */ public void setFinished(boolean finished) { this.finished = finished; } /** * @return the in */ public PipedInputStream getIn() { return in; } }
测试类:
package com.alibaba.stream.thread.test; import java.io.IOException; import org.junit.Test; import com.alibaba.stream.thread.Receiver; import com.alibaba.stream.thread.Sender; public class PipedStreamTest { public PipedStreamTest() { } @Test public void streamwithThreadTest() { String content = "Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言,\n" + "是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和\n" + "Java平台(即JavaSE, JavaEE, JavaME)的总称。Java 技术具有卓" + "越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台、" + "\n科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。在全球云计算" + "和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。"; Receiver rcv = new Receiver(); Sender s = new Sender(content, rcv); try { // 将管道连接 s.getOut().connect(rcv.getIn()); } catch (IOException e) { e.printStackTrace(); } Thread receiver = new Thread(rcv); Thread sender = new Thread(s); receiver.start(); // 不加这个sleep会出问题 ------>WHY??? try { Thread.sleep(3000);// 这个时间的大小也有影响 } catch (InterruptedException e) { e.printStackTrace(); } sender.start(); } }
问题就在于测试类中的sleep,如果不加这个或者数字 < 3000,就会出现问题,只打印sleeping,不会输出接收到的内容
但是如果先开sender,只要有sleep就可以跑,与sleep的时间长短并无关系