生产者和消费者模式
大学时学习操作系统多会为生产者和消费者模式而头痛,也是每次考试肯定会涉及到的,而Java知道大家很憷这个模式的并发复杂性,于是乎提供了阻塞队列(BlockingQueue)来满足这个模式的需求。阻塞队列说起来很简单,就是当队满的时候写线程会等待,直到队列不满的时候;当队空的时候读线程会等待,直到队不空的时候。实现这种模式的方法很多,其区别也就在于谁的消耗更低和等待的策略更优。以LinkedBlockingQueue的具体实现为例,它的put源码如下:
|
撇开其锁的具体实现,其流程就是我们在操作系统课上学习到的标准生产者模式,看来那些枯燥的理论还是有用武之地的。其中,最核心的还是Java的锁实现,有兴趣的朋友可以再进一步深究一下
阻塞和可中断方法
由LinkedBlockingQueue的put方法可知,它是通过线程的阻塞和中断阻塞来实现等待的。当调用一个会抛出InterruptedException的方法时,就成为了一个阻塞的方法,要为响应中断做好准备。处理中断可有以下方法:
● 传递InterruptedException。把捕获的InterruptedException再往上抛,使其调用者感知到,当然在抛之前需要完成你自己应该做的清理工作,LinkedBlockingQueue的put方法就是采取这种方式
● 中断其线程。在不能抛出异常的情况下,可以直接调用Thread.interrupt()将其中断。
Synchronizer
Synchronizer不是一个类,而是一种满足一个种规则的类的统称。它有以下特性:
● 它是一个对象
● 封装状态,而这些状态决定着线程执行到某一点是通过还是被迫等待
● 提供操作状态的方法
其实BlockingQueue就是一种Synchronizer。Java还提供了其他几种Synchronizer