阅读的书籍:《java疯狂讲义》
关键词:传统的线程通信,使用Condition控制线程通信,使用阻塞队列控制线程通信
传统的线程通信:利用Object类提供的wait(),notify(),notifyAll()三个方法
首先,这三个方法是属于Object类的,而不是Thread类;其次,这三个方法必须由同步监视器对象来调用
- 对于使用synchronized修饰的同步方法,因为该类的默认实例(this)就是同步监视器,所以可以在同步方法中直接调用这三个方法
- 对于使用synchronized修饰的同步代码块,同步监视器是synchronized后括号里的对象,所以要使用该对象来调用这三个方法
wait(),notify(),notifyAll()的解释:
wait():导致当前线程等待,直到其他线程调用该同步监视器的notify()或notifyAll()来唤醒该线程
notify():唤醒在此同步监视器上等待的单个线程。如果所有线程都在此同步监视器上等待,则会选择唤醒其中一个线程,选择是
任意的
notifyAll():唤醒在此同步监视器上等待的所有线程
使用Condition控制线程通信:当使用Lock对象来保证同步时,java提供Condition类来保持协调
如果程序不使用synchronized关键字来保证同步,而是直接使用Lock对象来保证同步,则系统不存在隐式的同步监视器,也就不能使用wait(),notify(),notifyAll()来进行线程通信了
使用方式:
Lock lock = new ReentrantLock();
Condition cond = lock.newCondition();
和Object类似的是,Condition也提供了三个方法:await(),signal(),signalAll()
使用阻塞队列控制线程通信:Java5提供了一个BlockingQueue接口,它的主要用途并不是作为容器,而是作为线程同步的工具
BlockingQueue的特点
- 当生产者线程试图向BlockingQueue中放入元素时,如果该队列已满,则该线程被阻塞
- 当消费者线程试图从BlockingQueue中取出元素时,如果该队列已空,则该线程被阻塞
BlockingQueue提供的两个支持阻塞的方法:put(E e),take()
BlockingQueue五个重要的实现类:
- ArrayBlockingQueue:基于数组实现的BlockingQueue队列
- LinkedBlockingQueue:基于链表实现的BlockingQueue队列
- PriorityBlockingQueue:和PriorityQueue类似,该队列取出元素时,取的是最小的元素
- SynchronousQueue:同步队列,对该队列的存,取必须交替进行
- DelayQueue:底层基于PriorityBlockingQueue实现,根据集合元素的getDelay()方法的返回值进行排序