jdk-ConcurrentLinkedQueue(二)
来源:互联网 发布:c语言可以用string类吗 编辑:程序博客网 时间:2024/05/01 13:29
第一篇详细画出了在入队和出队时的操作,看的真的很费时,说实话,我看了好几遍才动手开始画队列变换的图,并且在画图时还时不时的修正了很多次。。。总结出,对于jdk源码的话,多看几遍总能看出作者的意图的,不要害怕看不懂,看不懂第一遍,看二遍,三遍。
这次的博客去看下此类中的其他一些方法,准备为将来的使用坐下基础。
succ方法,向后推进方法,可以看出获取的是当前节点的后继节点,比较了 p 和next是否相等,在第一篇博客分析时,发现在出队情况下,是有可能出现next指向自身的节点,出现这个节点,意味着出队执行成功,并且设置了新的head节点,head节点指向了下一个有效的队列头。
final Node<E> succ(Node<E> p) { Node<E> next = p.next; return (p == next) ? head : next; }
1. item 不为null,更新head指向,并返回当前item值。
2.item为 null,判断当前节点是否到达了尾部,如果是尾部的话,更新head节点指于此,如果不是尾部的话,判断是够指向自身,都不是的话,p节点后移,重新获取下一个节点的item值。peek方法总的来说是获取head节点之后第一个有效节点。
public E peek() { restartFromHead: for (;;) { for (Node<E> h = head, p = h, q;;) { E item = p.item; if (item != null || (q = p.next) == null) { updateHead(h, p); return item; } else if (p == q) continue restartFromHead; else p = q; } } }first方法。返回的是head节点之后的第一个不为null的有效节点的item值,可以看见,如果当前节点到达尾部的话,会更新一下head的值,并且会判断当前尾部节点的item是否是null,是的话返回空节点,不是的话返回有效节点
Node<E> first() { restartFromHead: for (;;) { for (Node<E> h = head, p = h, q;;) { boolean hasItem = (p.item != null); if (hasItem || (q = p.next) == null) { updateHead(h, p); return hasItem ? p : null; } else if (p == q) continue restartFromHead; else p = q; } } }isEmpty 字面意思判空。
如果head处的节点item值不为null,那么first会立即返回这个节点,立马知道这个队列不空。
如果first返回的是null的话,说明从head处读取到之后的节点都为null一直到最后的尾部节点,依然是null,才最终返回null。注意此处是从head节点开始读取的,head节点在出队操作中会不断变化。那么只有在这个队列全为null时,才会去遍历整个队列。
public boolean isEmpty() { return first() == null; }可以看见size方法并不适用于判空处理,它会循环整个队列,计算出count值,消耗极大,并且这个count的值也不是准确的,多线程情况下有可能不靠谱,需要我们手动去做同步,注意一下。
public int size() { int count = 0; for (Node<E> p = first(); p != null; p = succ(p)) if (p.item != null) // Collection.size() spec says to max out if (++count == Integer.MAX_VALUE) break; return count; }contains方法,去队列中寻找是否包含这个item项的节点。跟size方法一样,使用succ方式去遍历,但是这个方法一样会出现数据不同步的情况。
public boolean contains(Object o) { if (o == null) return false; for (Node<E> p = first(); p != null; p = succ(p)) { E item = p.item; if (item != null && o.equals(item)) return true; } return false; }
使用ConcurrentLinkedQueue实现生产者消费者went
public class TestConcurrentLinkedDeque { public static void main(String[] args) { ConcurrentLinkedQueue<Food> foods = new ConcurrentLinkedQueue<Food>(); final Provider provider = new Provider(foods); final Customer customer = new Customer(foods); for(int i = 0; i < 10; i ++){ new Thread(new Runnable() { public void run() { provider.runP(); } }).start(); } for(int i = 0; i < 10; i ++){ new Thread(new Runnable() { public void run() { customer.runC(); } }).start(); } }}
public class Provider { private ConcurrentLinkedQueue<Food> foods; /*采用原子Integer,可以完美解决多线程环境下数目的变换*/ private AtomicInteger num = new AtomicInteger(); public Provider(ConcurrentLinkedQueue<Food> foods) { this.foods = foods; } public void runP() { // TODO Auto-generated method stub while (true) { int index = num.incrementAndGet(); String name = "甜品 "+index+" 号"; try { foods.offer(new Food(index, name)); System.out.println(Thread.currentThread()+"生产了第 "+ index + "号 食品: "+name + System.currentTimeMillis()); Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }}
public class Customer { private ConcurrentLinkedQueue<Food> foods; public Customer(ConcurrentLinkedQueue<Food> foods) { this.foods = foods; } public void runC() { // TODO Auto-generated method stub while (true) { try { Food food = foods.poll(); if(food == null){ System.err.println(Thread.currentThread()+ "消费失败,无数据生产出 " +System.currentTimeMillis()); }else { System.err.println(Thread.currentThread()+ "消费了第 "+food.getNum()+"食品 : " + food.getName()+System.currentTimeMillis()); Thread.sleep(2000); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }}
Thread[Thread-0,5,main]生产了第 1号 食品: 甜品 1 号1496710329448Thread[Thread-2,5,main]生产了第 2号 食品: 甜品 2 号1496710329448Thread[Thread-4,5,main]生产了第 3号 食品: 甜品 3 号1496710329449Thread[Thread-6,5,main]生产了第 4号 食品: 甜品 4 号1496710329449Thread[Thread-8,5,main]生产了第 5号 食品: 甜品 5 号1496710329449Thread[Thread-10,5,main]消费了第 1食品 : 甜品 1 号1496710329450Thread[Thread-12,5,main]消费了第 2食品 : 甜品 2 号1496710329450Thread[Thread-14,5,main]消费了第 3食品 : 甜品 3 号1496710329450Thread[Thread-16,5,main]消费了第 4食品 : 甜品 4 号1496710329451Thread[Thread-18,5,main]消费了第 5食品 : 甜品 5 号1496710329451Thread[Thread-11,5,main]消费了第 6食品 : 甜品 6 号1496710329451Thread[Thread-13,5,main]消费了第 7食品 : 甜品 7 号1496710329451Thread[Thread-15,5,main]消费了第 8食品 : 甜品 8 号1496710329451Thread[Thread-17,5,main]消费了第 9食品 : 甜品 9 号1496710329451Thread[Thread-19,5,main]消费了第 10食品 : 甜品 10 号1496710329452Thread[Thread-1,5,main]生产了第 6号 食品: 甜品 6 号1496710329451Thread[Thread-3,5,main]生产了第 7号 食品: 甜品 7 号1496710329451Thread[Thread-5,5,main]生产了第 8号 食品: 甜品 8 号1496710329451Thread[Thread-7,5,main]生产了第 9号 食品: 甜品 9 号1496710329451Thread[Thread-9,5,main]生产了第 10号 食品: 甜品 10 号1496710329451Thread[Thread-10,5,main]消费了第 12食品 : 甜品 12 号1496710331450Thread[Thread-14,5,main]消费了第 13食品 : 甜品 13 号1496710331450Thread[Thread-12,5,main]消费了第 11食品 : 甜品 11 号1496710331450Thread[Thread-18,5,main]消费了第 14食品 : 甜品 14 号1496710331451Thread[Thread-16,5,main]消费了第 15食品 : 甜品 15 号1496710331451Thread[Thread-11,5,main]消费了第 16食品 : 甜品 16 号1496710331451Thread[Thread-13,5,main]消费了第 17食品 : 甜品 17 号1496710331451Thread[Thread-15,5,main]消费了第 18食品 : 甜品 18 号1496710331451Thread[Thread-0,5,main]生产了第 11号 食品: 甜品 11 号1496710331448Thread[Thread-17,5,main]消费了第 19食品 : 甜品 19 号1496710331452Thread[Thread-2,5,main]生产了第 12号 食品: 甜品 12 号1496710331448Thread[Thread-19,5,main]消费了第 20食品 : 甜品 20 号1496710331452Thread[Thread-4,5,main]生产了第 13号 食品: 甜品 13 号1496710331449Thread[Thread-6,5,main]生产了第 14号 食品: 甜品 14 号1496710331449Thread[Thread-8,5,main]生产了第 15号 食品: 甜品 15 号1496710331449Thread[Thread-1,5,main]生产了第 16号 食品: 甜品 16 号1496710331451Thread[Thread-3,5,main]生产了第 17号 食品: 甜品 17 号1496710331451Thread[Thread-9,5,main]生产了第 18号 食品: 甜品 18 号1496710331451Thread[Thread-5,5,main]生产了第 19号 食品: 甜品 19 号1496710331451Thread[Thread-7,5,main]生产了第 20号 食品: 甜品 20 号1496710331451Thread[Thread-10,5,main]消费了第 21食品 : 甜品 21 号1496710333450Thread[Thread-12,5,main]消费了第 22食品 : 甜品 22 号1496710333450Thread[Thread-14,5,main]消费了第 23食品 : 甜品 23 号1496710333450Thread[Thread-16,5,main]消费了第 24食品 : 甜品 24 号1496710333451Thread[Thread-18,5,main]消费了第 25食品 : 甜品 25 号1496710333451Thread[Thread-11,5,main]消费了第 26食品 : 甜品 26 号1496710333451Thread[Thread-15,5,main]消费失败,无数据生产出 1496710333451Thread[Thread-15,5,main]消费失败,无数据生产出 1496710333451Thread[Thread-15,5,main]消费失败,无数据生产出 1496710333451Thread[Thread-15,5,main]消费了第 27食品 : 甜品 27 号1496710333451Thread[Thread-13,5,main]消费了第 28食品 : 甜品 28 号1496710333451Thread[Thread-0,5,main]生产了第 21号 食品: 甜品 21 号1496710333448Thread[Thread-2,5,main]生产了第 22号 食品: 甜品 22 号1496710333448Thread[Thread-4,5,main]生产了第 23号 食品: 甜品 23 号1496710333449Thread[Thread-6,5,main]生产了第 24号 食品: 甜品 24 号1496710333449Thread[Thread-8,5,main]生产了第 25号 食品: 甜品 25 号1496710333449Thread[Thread-3,5,main]生产了第 26号 食品: 甜品 26 号1496710333451Thread[Thread-1,5,main]生产了第 27号 食品: 甜品 27 号1496710333451Thread[Thread-9,5,main]生产了第 28号 食品: 甜品 28 号1496710333451Thread[Thread-5,5,main]生产了第 29号 食品: 甜品 29 号1496710333451Thread[Thread-7,5,main]生产了第 30号 食品: 甜品 30 号1496710333451Thread[Thread-17,5,main]消费了第 29食品 : 甜品 29 号1496710333452Thread[Thread-19,5,main]消费了第 30食品 : 甜品 30 号1496710333452Thread[Thread-0,5,main]生产了第 31号 食品: 甜品 31 号1496710335449Thread[Thread-2,5,main]生产了第 32号 食品: 甜品 32 号1496710335449Thread[Thread-4,5,main]生产了第 33号 食品: 甜品 33 号1496710335450Thread[Thread-8,5,main]生产了第 34号 食品: 甜品 34 号1496710335450Thread[Thread-6,5,main]生产了第 35号 食品: 甜品 35 号1496710335450Thread[Thread-3,5,main]生产了第 36号 食品: 甜品 36 号1496710335452Thread[Thread-1,5,main]生产了第 37号 食品: 甜品 37 号1496710335452Thread[Thread-9,5,main]生产了第 38号 食品: 甜品 38 号1496710335452Thread[Thread-5,5,main]生产了第 39号 食品: 甜品 39 号1496710335452Thread[Thread-7,5,main]生产了第 40号 食品: 甜品 40 号1496710335452Thread[Thread-10,5,main]消费了第 31食品 : 甜品 31 号1496710335451Thread[Thread-12,5,main]消费了第 32食品 : 甜品 32 号1496710335451Thread[Thread-14,5,main]消费了第 33食品 : 甜品 33 号1496710335451Thread[Thread-16,5,main]消费了第 34食品 : 甜品 34 号1496710335452Thread[Thread-18,5,main]消费了第 35食品 : 甜品 35 号1496710335452Thread[Thread-11,5,main]消费了第 36食品 : 甜品 36 号1496710335452Thread[Thread-13,5,main]消费了第 37食品 : 甜品 37 号1496710335452Thread[Thread-15,5,main]消费失败,无数据生产出 1496710335452Thread[Thread-15,5,main]消费了第 38食品 : 甜品 38 号1496710335452Thread[Thread-17,5,main]消费了第 39食品 : 甜品 39 号1496710335453Thread[Thread-19,5,main]消费了第 40食品 : 甜品 40 号1496710335453
实现方式和LinkBlobkedQueue类似
阅读全文
0 0
- jdk-ConcurrentLinkedQueue(二)
- ConcurrentLinkedQueue学习(二)
- jdk-ConcurrentLinkedQueue(一)
- jdk concurrent collection---ConcurrentLinkedQueue原理分析
- jdk concurrent collection---ConcurrentLinkedQueue原理分析
- ConcurrentLinkedQueue原理(上)
- ConcurrentLinkedQueue原理(上)
- ConcurrentLinkedQueue学习(一)
- ConcurrentLinkedQueue学习(三)
- ConcurrentLinkedQueue原理(上)
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- JSON实战之savegame(Qt Example)
- Java注释规范整理
- java ,jquery 生成 qrcode 二维码带Logo
- PHP程序员的进阶之路
- 增强学习Q-learning 算法的简明教程
- jdk-ConcurrentLinkedQueue(二)
- cordova build android 报异常 not reserve enough space 解决方法
- [js]多个按钮点击添加div,再点击删除
- 破解前端面试系列(3):如何搞定纸上代码环节?
- 单据头F7字段、分录F7字段,数据过滤,过滤条件添加
- SpringBoot应用之配置中心
- Linux基础-8(nfs)
- 面向对象三大基本特性、五大基本原则
- 持久层