一、BlockingQueue
BlockingQueue是java.util.concurrent包下的一个接口,它是一个线程安全的队列,所以它最典型的用途就是生产者-消费者模式。
生产线程生产对象放入队列,如果队列放满,该线程就处于阻塞状态,直到消费线程从队列中取出对象进行消费。
消费线程从队列中取出对象进行消费,如果队列为空,该线程处于阻塞状态,直到生产线程生成一个新对象放入队列。
BlockingQueue的方法
方法总是分为三类:插入,删除,查看。
可以看到上面三类方法分四种不同行为:
- Throws Exception: 如果操作无法立刻执行,就会抛出异常
- Special Value: 如果执行的操作无法立刻执行,就会返回一个指定的值(通常为true和false)
- Blocks: 如果执行的操作无法立刻执行,就会阻塞,直到该操作可以执行
- Times Out: 如果执行的操作无法立刻执行,就会阻塞,并且设置有一个阻塞时间,如果在这个时间内还是不能执行到,就算超时,它会返回一个执行的值代表是否执行成功(通常为true和false)。
BlockingQueue的实现类
ArrayBlockingQueue
DelayQueue
LinkedBlockingQueue
PriorityBlockingQueue
SynchronousQueue
例子:
public class BlockingQueueExample {
public static void main(String[] args) throws Exception {
BlockingQueue queue = new ArrayBlockingQueue(1024);
Producer producer = new Producer(queue);
Consumer consumer = new Consumer(queue);
new Thread(producer).start();
new Thread(consumer).start();
Thread.sleep(4000);
}
}
public class Producer implements Runnable{
protected BlockingQueue queue = null;
public Producer(BlockingQueue queue) {
this.queue = queue;
}
public void run() {
try {
queue.put("1");
Thread.sleep(1000);
queue.put("2");
Thread.sleep(1000);
queue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Consumer implements Runnable{
protected BlockingQueue queue = null;
public Consumer(BlockingQueue queue) {
this.queue = queue;
}
public void run() {
try {
System.out.println(queue.take());
System.out.println(queue.take());
System.out.println(queue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
下面来具体看看它的几个实现类:
二、ArrayBlockingQueue
从名字也可以看出,这个队列是使用一个数组来存放对象元素。
基本用法:
BlockingQueue queue = new ArrayBlockingQueue(1024);
queue.put("1");
Object object = queue.take();
三、DelayQueue
DelayQueue是一个延迟队列,用于放置实现了Delayed接口的对象,其中的对象只能在指定的延迟时间点上才能从队列中取走。
public interface Delayed extends Comparable<Delayed> {
public long getDelay(TimeUnit timeUnit);
}
队列中的每个对象都必须实现这个接口,getDelay方法为延迟的时间,也就是该对象必须延迟指定的时间才能被取走。
TimeUnit是一个Enum类型,包括以下值:
DAYS
HOURS
MINUTES
SECONDS
MILLISECONDS
MICROSECONDS
NANOSECONDS
例子:
public class DelayQueueExample {
public static void main(String[] args) {
DelayQueue queue = new DelayQueue();
Delayed element1 = new DelayedElement();
queue.put(element1);
Delayed element2 = queue.take();
}
}
四、LinkedBlockingQueue
这个跟ArrayBlockingQueue类似,只是它的队列实现是链表。
例子:
BlockingQueue<String> unbounded = new LinkedBlockingQueue<String>();
BlockingQueue<String> bounded = new LinkedBlockingQueue<String>(1024);
bounded.put("Value");
String value = bounded.take();
五、PriorityBlockingQueue
一个无界的阻塞队列,它里面存放的对象可以进行比较,并且具有优先级,它使用与类 PriorityQueue 相同的顺序规则,并且提供了阻塞检索的操作。
因为它里面存放的对象具有优先级,并且进行了优先级排序,所以所有的对象必须实现Comparable接口。
例子:
BlockingQueue queue = new PriorityBlockingQueue();
//String implements java.lang.Comparable
queue.put("Value");
String value = queue.take();
六、SynchronousQueue
这个队列的特定就是他的队列里面只能存放一个对象,当一个线程放入一个对象之后就处于阻塞状态,等待另一个线程将对象取出之后,它才能接着放入对象。