首页 新闻 赞助 找找看

在线程间用管道流通信问题

0
悬赏园豆:15 [待解决问题]

有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的时间长短并无关系

rm_rf的主页 rm_rf | 初学一级 | 园豆:6
提问于:2017-12-26 10:44
< >
分享
所有回答(0)
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册