使用BlockingQueue进行线程间通信(java)

我们可以使用管道进行线程间通信,Java IO中提供了PipedWriter类和PipedReader类让线程间通信,《Java编程思想》在21.5.5节提供了例子。但是,Java提供了更健壮和容易的方式,即阻塞队列BlockingQueue来解决所有线程间协作的问题。所以,我们可以用BlockingQueue来实现线程间通信,原理很简单,一个线程向队列中添加元素,而另一个线程从队列中获取元素。

贴代码:(修改21.5.5的PipedIO.java,参考了21.5.4的吐司BlockingQueue程序ToastOMatic.java)

import java.util.concurrent.*;
import java.util.*;

class MessageQueue extends LinkedBlockingQueue<Character> {}

class Sender implements Runnable {
    private Random rand = new Random(47);
    private MessageQueue messageQueue;
    public Sender(MessageQueue mq) { messageQueue = mq; }
    public void run() {
        try {
            while(!Thread.interrupted())
                for (char c = 'A'; c <= 'z'; c++) {
                    messageQueue.put(c);
                    TimeUnit.MILLISECONDS.sleep(rand.nextInt(500));
                }
        } catch(InterruptedException e) {
            System.out.println(e + " Sender sleep interrupted");
        }
    }
}

class Receiver implements Runnable {
    private MessageQueue messageQueue;
    public Receiver(MessageQueue mq) { messageQueue = mq; }
    public void run() {
        try {
            while(!Thread.interrupted()) {
                System.out.print("Read: " + messageQueue.take() + ", ");
            }
        } catch(InterruptedException e) {
            System.out.println(e + " Receiver read exception");
        }
    }
}

public class BlockingQueueIO {
    public static void main(String[] args) throws Exception {
        MessageQueue messageQueue = new MessageQueue();
        ExecutorService exec = Executors.newCachedThreadPool();
        exec.execute(new Sender(messageQueue));
        exec.execute(new Receiver(messageQueue));
        TimeUnit.SECONDS.sleep(4);
        exec.shutdownNow();
    }
} 

编译并运行之后结果:

Read: A, Read: B, Read: C, Read: D, Read: E, Read: F, Read: G, Read: H, Read: I, Read: J, Read: K, Read: L, Read: M, Read: N, Read: O, Read: P, Read: Q, java.lang.InterruptedException Receiver read exception
java.lang.InterruptedException: sleep interrupted Sender sleep interrupted

我们可以看到,Sender和Receiver两个线程共用一个BlockingQueue,更多的线程都能使用同一个阻塞队列进行通信。每个线程都只和这个BlockingQueue通信,线程之间实际上没有直接的通信。而使用管道,其实两个线程是耦合在一起的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值