java.util.concurrent系列之--ConcurrentLinkedQueue

一、ConcurrentLinkedQueue介绍

ConcurrentLinkedQueue是线程安全的队列,它适用于“高并发”的场景。它是一个基于链接节点的无界线程

安全队列,按照 FIFO(先进先出)原则对元素进行排序。队列元素中不可以放置null元素(内部实现的特殊

节点除外)。

二、ConcurrentLinkedQueue原理和数据结构

ConcurrentLinkedQueue的数据结构,如下图所示:

输入图片说明

说明:

1. ConcurrentLinkedQueue继承于AbstractQueue。

2. ConcurrentLinkedQueue内部是通过链表来实现的。它同时包含链表的头节点head和尾节点tail。

ConcurrentLinkedQueue按照 FIFO(先进先出)原则对元素进行排序。元素都是从尾部插入到链表,从头

部开始返回。

3. ConcurrentLinkedQueue的链表Node中的next的类型是volatile,而且链表数据item的类型也是

volatile。关于volatile,我们知道它的语义包含:“即对一个volatile变量的读,总是能看到(任意线程)对这

个volatile变量最后的写入”。ConcurrentLinkedQueue就是通过volatile来实现多线程对竞争资源的互斥访

问的。

三、ConcurrentLinkedQueue原理和数据结构

// 创建一个最初为空的 ConcurrentLinkedQueue。
ConcurrentLinkedQueue()

// 创建一个最初包含给定 collection 元素的 ConcurrentLinkedQueue,按照此 collection 迭代器的遍历顺序来添加元素。
ConcurrentLinkedQueue(Collection<? extends E> c)

// 将指定元素插入此队列的尾部。
boolean add(E e)

// 如果此队列包含指定元素,则返回 true。
boolean contains(Object o)

// 如果此队列不包含任何元素,则返回 true。
boolean isEmpty()

// 返回在此队列元素上以恰当顺序进行迭代的迭代器。
Iterator<E> iterator()

// 将指定元素插入此队列的尾部。
boolean offer(E e)

// 获取但不移除此队列的头;如果此队列为空,则返回 null。
E peek()

// 获取并移除此队列的头,如果此队列为空,则返回 null。
E poll()

// 从队列中移除指定元素的单个实例(如果存在)。
boolean remove(Object o)

// 返回此队列中的元素数量。
int size()

// 返回以恰当顺序包含此队列所有元素的数组。
Object[] toArray()

// 返回以恰当顺序包含此队列所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。
<T> T[] toArray(T[] a)

四、ConcurrentLinkedQueue示例

import java.util.*;
import java.util.concurrent.*;

/*
*   ConcurrentLinkedQueue是“线程安全”的队列,而LinkedList是非线程安全的。
*
*   下面是“多个线程同时操作并且遍历queue”的示例
*   (01) 当queue是ConcurrentLinkedQueue对象时,程序能正常运行。
*   (02) 当queue是LinkedList对象时,程序会产生ConcurrentModificationException异常。
*
* @author skywang
*/
public class ConcurrentLinkedQueueDemo1 {

    // TODO: queue是LinkedList对象时,程序会出错。
    //private static Queue<String> queue = new LinkedList<String>();
    private static Queue<String> queue = new ConcurrentLinkedQueue<String>();

    public static void main(String[] args) {

        // 同时启动两个线程对queue进行操作!
        new MyThread("ta").start();
        new MyThread("tb").start();
    }

    private static void printAll() {
        String value;
        Iterator iter = queue.iterator();
        while (iter.hasNext()) {
            value = (String) iter.next();
            System.out.print(value + ", ");
        }
        System.out.println();
    }

    private static class MyThread extends Thread {
        MyThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            int i = 0;
            while (i++ < 6) {
                // “线程名” + "-" + "序号"
                String val = Thread.currentThread().getName() + i;
                queue.add(val);
                // 通过“Iterator”遍历queue。
                printAll();
            }
        }
    }
}

结果说明:如果将源码中的queue改成LinkedList对象时,程序会产生ConcurrentModificationException异常。

五、转载地址

http://www.cnblogs.com/skywang12345/p/3498995.html

转载于:https://my.oschina.net/u/3136594/blog/1594421

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值