kim.zhang

风在前,无惧!


  • 首页

  • 标签42

  • 分类12

  • 归档94

  • 搜索

并发队列.md

发表于 2020-08-10 更新于 2021-11-21 分类于 并发
本文字数: 2.8k 阅读时长 ≈ 3 分钟

并发-无阻塞队列

ConcurrentLinkedQueue并发无阻塞队列,BlockingQueue并发阻塞队列。

ConcurrentLinkedQueue实现Queue接口,BlockingQueue本身是一个接口,继承Queue接口。

ConcurrentLinkedQueue

    • 无阻赛、无锁、高性能、无界队列(直至内存耗尽)、线程安全,性能优于BlockingQueue、不允许null值
    • 使用CAS算法进行入队和出队操作

栗子1:ConcurrentLinkedQueue基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class DemoThread29 {

public static void main(String[] args) {

ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<>();

queue.add(1);
// add方法实际调用了offer方法
queue.add(2);
// offer方法与add没有区别
queue.offer(3);
queue.offer(4);

//不允许添加null元素
// queue.add(null);
System.out.println(queue);
System.out.println("[1]peek=" + queue.peek()); //读取头元素,但是不移除
System.out.println("[2]size=" + queue.size()); //peek方法不会导致size改变

System.out.println("[3]poll=" + queue.poll()); //读取头元素,并且移除
System.out.println("[4]size=" + queue.size()); //poll方法导致size改变

System.out.println("[5]poll=" + queue.poll());
System.out.println("[6]poll=" + queue.poll());
System.out.println("[7]poll=" + queue.poll());
System.out.println("[8]size=" + queue.size());

System.out.println("peek=" + queue.peek()); //队列为空, 读取头元素,返回null
System.out.println("pool=" + queue.poll()); //队列为空, 读取头元素并移除, 返回null
}
}

执行结果:

1
2
3
4
5
6
7
8
9
10
11
[1, 2, 3, 4]
[1]peek=1
[2]size=4
[3]poll=1
[4]size=3
[5]poll=2
[6]poll=3
[7]poll=4
[8]size=0
peek=null
pool=null

ArrayBlockingQueue

  • 不允许添加null元素,三种添加方法都不允许添加null元素

  • 添加方法

    • add:如果队列满了,抛出异常

      • 1
        java.lang.IllegalStateException: Queue full
    • offer:如果队列满了,不阻塞,不抛出异常。可以设置最大阻塞时间。

      • 1
        2
        // 可设置最大阻塞时间,5秒,如果队列还是满的,则不阻塞,不抛出异常
        queue.offer(6, 5, TimeUnit.SECONDS);
    • put:如果队列满了,永远阻塞,不抛出异常

  • 获取方法

    • peek:读取头元素不移除。如果队列为空,返回null,不阻塞, 不抛异常

    • poll:读取头元素,并移除。如果队列为空,返回null,不阻塞, 不抛异常。可以设置最大最大阻塞时间

      • 1
        2
        // 可指定阻塞时间,2秒,如果队列依然为空,则返回null,不抛异常
        queue.poll(2, TimeUnit.SECONDS)
    • take:读取头元素,并移除。如果队列为空,则永远阻塞,不抛出异常

  • 转换方法

    • drainTo:取出queue中指定个数的元素放入集合中,并移除。如果队列为空时,不阻塞,不抛出异常

      • 1
        queue.drainTo(list, 2);

栗子1:drainTo转换为List

1
2
3
4
5
6
7
8
9
10
11
public static void testTake2() {
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(3);
queue.add(1);
queue.add(2);
queue.add(3);

ArrayList<Integer> list = new ArrayList<Integer>();
queue.drainTo(list, 2); // 取出queue中指定个数的元素放入list中,并移除
System.out.println("list>>" + list);
System.out.println("queue>>" + queue);
}

执行结果:

1
2
list>>[1, 2]
queue>>[3]

栗子2:空队列drainTo转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void testTake3() {
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(3);
queue.add(1);
queue.add(2);
queue.add(3);

ArrayList<Integer> list = new ArrayList<Integer>();
queue.drainTo(list); // 取出queue中的全部元素放入list中,并移除
System.out.println("1>>" + list);
System.out.println("2>>" + queue);

ArrayList<Integer> list1 = new ArrayList<Integer>();
queue.drainTo(list1); // 当队列为空时不抛出异常
System.out.println("3>>" + list1);
System.out.println("4>>" + queue);
}

执行结果:

1
2
3
4
1>>[1, 2, 3]
2>>[]
3>>[]
4>>[]
一毛也是爱~
Kim.Zhang 微信支付

微信支付

# JUC
线程池.md
可见性.md
  • 文章目录
  • 站点概览
Kim.Zhang

Kim.Zhang

且行且珍惜
94 日志
12 分类
42 标签
E-Mail Weibo
  1. 1. 并发-无阻塞队列
    1. 1.1. 栗子1:ConcurrentLinkedQueue基本操作
  2. 2. ArrayBlockingQueue
    1. 2.1. 栗子1:drainTo转换为List
    2. 2.2. 栗子2:空队列drainTo转换
粵ICP备19091267号 © 2019 – 2022 Kim.Zhang | 629k | 9:32
本站总访问量 4 次 | 有 309 人看我的博客啦 |
博客全站共176.7k字
载入天数...载入时分秒...
0%