Java 多线程 任务间使用管道进行输入/输出

    通过输入/输出在线程间进行通信通常很有用。提供线程功能的类库以“管道”的形式对线程的输入/输出提供了支持。它们在Java输入/输出类库中的对应物就是PipedWriter类(允许任务向管道写)和PipedReader类(允许不同任务从同一个管道中读取)。这个模型可以看成是“生产者-消费者”问题的变体,这里的管道就是一个封装好的解决方案。管道基本上是一个阻塞队列,存在于多个引入BlockingQueue之前的Java版本中。


import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 这是一个简单的例子,两个任务使用一个管道进行通信:
 * 
 * @create @author Henry @date 2016-12-23
 * 
 */
class Sender implements Runnable {
	private Random rand = new Random(47);
	private PipedWriter out = new PipedWriter();
	
	public PipedWriter getPipedWriter(){
		return out;
	}

	@Override
	public void run() {
		try{
			while(true)
				for(char c='A';c<='z';c++){
					out.write(c);
					TimeUnit.MILLISECONDS.sleep(rand.nextInt(500));
				}
		}catch(IOException e){
			System.err.println(e+" Sender write exception");
		} catch (InterruptedException e) {
			System.err.println(e+" Sender sleep interrupted");
		}
	}
}

class Receiver implements Runnable{
	private PipedReader in;
	public Receiver(Sender sender) throws IOException{
		in=new PipedReader(sender.getPipedWriter());
	}
	@Override
	public void run() {
		try{
			while(true){
				//Blocks until characters are there
				System.out.println("Read: "+(char)in.read()+". ");
			}
		}catch(IOException e){
			System.err.println(e+" Receiver read exception");
		}
	}
	
}
/**
 * Sender和Receiver代表了需要互相通信两个任务。Sender创建了一个PipedWriter,它是一个单独的对象;但是对于Received,
 * PipedReader的建立必须在构造器中与一个PipedWriter相关联。Sender把数据放进Writer,然后休眠一段时间(随机数)。然而,
 * Receiver没有sleep()和wait()。相当它调用read()时,如果没有更多的数据,管道将自动阻塞。
 * 
 * 注意sender和receiver是在main()中启动的,即对象构造彻底完毕以后。如果你启动了一个没有构造完毕的对象,在不同的平台上
 * 管道可能会产生不一致的行为(注意,BlockingQueue使用起来更加健壮而容易)。
 * 
 * 在shutdownNow()被调用时,可以看到PipedReader与普通I/O之间最重要的差异--PipedReader是可中断的。如果你将in.read()
 * 调用修改为System.in.read(),那么interrupt()将不能打断read()调用。
 * 
 * @create @author Henry @date 2016-12-23
 * 
 */
public class PipedIO {
	public static void main(String[] args) throws Exception {
		Sender sender =new Sender();
		Receiver receiver=new Receiver(sender);
		ExecutorService exec=Executors.newCachedThreadPool();
		exec.execute(sender);
		exec.execute(receiver);
		TimeUnit.SECONDS.sleep(4);
		exec.shutdownNow();
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值