1.1 并发Queue
在并发队列上JDK提供了两套实现,一个是以ConcurrentLinkedQueue为代表的高性能队列,一个是以BlockingQueue接口为代表的阻塞队列,无论哪种都继承自Queue。
1.2 ConcurrentLinkedQueue
ConcurrentLinkedQueue:是一个适用于高并发场景下的队列,通过无锁的方式,实现了高并发下的高性能,通常ConcurrentLinkedQueue性能好于BlockingQueue。它是一个基于链接节点的无界线程安全队列。该队列的元素遵循先进先出的原则。头是最先加入的,尾是最近加入的,该队列不允许null元素。
ConcurrentLinkedQueue重要方法:
add()和offer() 都是加入元素的方法(在ConcurrentLinkedQueue中这两个方法没有任何区别)
poll()和peek() 都是取头元素节点,区别在于前者会删除元素,后者不会。
1.3 BlockingQueue接口
ArrayBlockingQueue –基于数组实现的一个阻塞队列,在创建ArrayBlockingQueue对象时必须制定容量大小,以便缓存队列中的数据对象,其内部没有实现读写分离,即生产者和消费者不能完全并行。并且可以指定公平性与非公平性,默认情况下为非公平的,即不保证等待时间最长的线程最优先能够访问队列。 有界队列
LinkedBlockingQueue–基于链表实现的一个阻塞队列,在创建LinkedBlockingQueue对象时如果不指定容量大小,则默认大小为Integer.MAX_VALUE。 内部采用分离锁(读写分离两个锁),从而实现生产者和消费者操作的完全并行运行。无界队列
SynchronousQueue –同步阻塞队列,队列大小为1,一个元素要放到该队列中必须有一个线程在等待获取元素。
PriorityBlockingQueue–无界阻塞队列,它会按照元素的优先级对元素进行排序,按照优先级顺序出队,每次出队的元素都是优先级最高的元素。
DelayQueue –基于PriorityQueue实现的延迟队列,是一个无界的阻塞队列,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。因此向队列中插入时永远不会阻塞,获取时才有可能被阻塞。
DelayedWorkQueue –该队列为ScheduledThreadPoolExecutor中的静态内部类,ScheduledThreadPoolExecutor便是通过该队列使得队列中的元素按一定顺序排列从而时延迟任务和周期性任务得以顺利执行。
BlockingDeque–双向阻塞队列的接口。
TransferQueue–接口,定义了另一种阻塞情况:生产者会一直阻塞直到所添加到队列的元素被某一个消费者所消费,而BlockingQueue只需将元素添加到队列中后生产者便会停止被阻塞。
示例:
public class MyBlockingQueue {
public static void main(String[] args) throws InterruptedException { ArrayBlockingQueue<String> array = new ArrayBlockingQueue<String>(5);//指定队列大小
//array.offer("a",2,TimeUnit.SECONDS);//两秒内加进去就返回true,否则返回false array.put("b"); array.add("c"); array.add("d"); array.add("e"); /** * offer 可以是设定阻塞时间的 * put 不具备该参数 */ //两秒内加进去就返回true,否则返回false System.out.println(array.offer("a",2,TimeUnit.SECONDS)); //--------------------------------------------------------------------------------------------- LinkedBlockingQueue<String> q = new LinkedBlockingQueue<String>();//无界的,可指定大小,可不指定
//array.offer("a",2,TimeUnit.SECONDS);//两秒内加进去就返回true,否则返回false q.put("b"); q.add("c"); q.add("d"); q.add("e"); q.add("f"); //q.add("g"); List<String> list = new ArrayList<String>(); /** * 在q队列中去3个值放到list中 */ q.drainTo(list,3); for(Iterator iterator = q.iterator();iterator.hasNext();) { String string = (String)iterator.next(); System.out.println(string); } //------------------------------------------------------------------ /** * SynchronousQueue是不允许加元素的 如果一个take方法在阻塞中,那是可以加add方法的 */ SynchronousQueue<String> sq = new SynchronousQueue<String>(); //------------------------------------------------------------------ PriorityBlockingQueue<String> pbq = new PriorityBlockingQueue<String>(); pbq.add("f"); pbq.add("e"); pbq.add("a"); for(String s : pbq) { System.out.println(s); //结果是afe,因为该队列采用得小顶堆,每次第一个元素取走后,再使得堆顶是最小的元素 //如果使用poll方法的话就会打印出有序的字符串 } } }
|