一、传统线程通信方式
Object类提供了三个方法:wait()、notify()、notifyAll()
这三个方法必须由同步监视器对象来调用
wait():导致当前线程等待,使用wait方法会导致当前线程释放对同步监视器的锁定,直到其他线程调用该同步监视器的notify()方法或notifyAll()方法来唤醒该线程。
notify():唤醒在此同步监视器上等待的所有线程,如果由多个线程在等待此同步监视器,则任意选择一个线程来唤醒。
notifyAll():唤醒所有调用了该同步监视器对象的wait方法的线程。
二、使用Condition控制线程通信
如果使用Lock来保证同步,就需要使用Condition通信。Lock+Condition的用法如下
private final Lock lock = new ReentrantLock(); private final Condition cond = lock.newCondition();
如此一来就可以在方法中第哦呵用cond 的await()、signal()、signalAll()方法了。
三、使用阻塞队列(BlockingQueue)控制线程通信
阻塞队列的问题模型其实是生产者消费者问题。
java5提供了一个BlockingQueue接口,这是Queue的子接口,但它主要作用不是作为容器,而是用于线程间“生产者消费者”模型的通信。
BlockingQueue接口提供如下方法:
- add(E e)、offer(E e)、put(E e),这三个方法都会向队列尾部插入元素,当队列满时,add抛出异常,offer返回false,put阻塞队列;
- remove()、poll()、take(),在队列头部取出并删除元素,当该队列已空时,分别抛出异常、返回false、阻塞队列;
- element()、peek(),在队列头部取出但是不删除元素,当队列空时,分别抛出异常、返回false。
BlockingQueue接口及其实现类的关系:
在使用该数据结构的时候可以查一下,下面简单说明:
LinkedBlockingQueue:基于链表实现的阻塞队列,ArrayBlockingQueue基于数组实现的阻塞队列,SynchronousQueue同步队列,读取操作只能交替进行,PriorityBlockingQueue优先级阻塞队列,预留排序接口,并且取出元素时并不是取出存在时间最长的元素,而是最小的元素,DelayQueue底层基于PriorityBlockingQueue实现,不过DelayQueue要求集合元素都实现Delay接口(该接口为函数式接口,方法为 long getDelay(),可根据该方法的返回值进行排序).