范文健康探索娱乐情感热点
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

java集合包LinkedBlockingQueue底层源码分析

  一、demopublic class LinkedBlockingQueueTest {     public static void main(String[] args) throws Exception{         LinkedBlockingQueue linkedBlockingQueue = new LinkedBlockingQueue(10);         linkedBlockingQueue.put("今天头条");         System.out.println(linkedBlockingQueue.take());         Iterator iterator = linkedBlockingQueue.iterator();         while (iterator.hasNext()){             System.out.println(iterator.next());         }     } }二、构造方法分析
  Condition:如果你获取了一把锁,然后调用了Condition.await(),此时会释放锁,当前线程会进入一个cnodition等待队列,事后人家来唤醒你,Cnodition.signal(),这个时候会从condition等待队列中把你加入到wait等待队列里去,然后人家释放锁,就会唤醒wait等待队列里的线程尝试来获取锁;		/** 当前队列元素数量 */	 		private final AtomicInteger count = new AtomicInteger(); 		/** Lock held by take, poll, etc */ 		/** 获取队列元素时加的锁 */     private final ReentrantLock takeLock = new ReentrantLock();      /** Wait queue for waiting takes */     private final Condition notEmpty = takeLock.newCondition();      /** Lock held by put, offer, etc */ 		/** 放入元素时加的锁*/     private final ReentrantLock putLock = new ReentrantLock();      /** Wait queue for waiting puts */     private final Condition notFull = putLock.newCondition();  public LinkedBlockingQueue(int capacity) {     if (capacity <= 0) throw new IllegalArgumentException();   	/** 队列最大大小 */     this.capacity = capacity;   	/** last和head指针指向空节点 */     last = head = new Node(null); }三、put方法public void put(E e) throws InterruptedException {     if (e == null) throw new NullPointerException();     // Note: convention in all put/take/etc is to preset local var     // holding count negative to indicate failure unless set.     int c = -1;   	/** 创建一个单向节点 */     Node node = new Node(e);   	/** 获取添加元素的锁 */     final ReentrantLock putLock = this.putLock;   	/** 获取队列当前数量 */     final AtomicInteger count = this.count;   	/** 加一个可以被中断的锁,保证同一时间只有一个线程可以添加数据     	* 如果加锁线程被中断了,此时加锁会失败,抛出一个线程中断的异常出来       */     putLock.lockInterruptibly();     try {         /*          * Note that count is used in wait guard even though it is          * not protected by lock. This works because count can          * only decrease at this point (all other puts are shut          * out by lock), and we (or some other waiting put) are          * signalled if it ever changes from capacity. Similarly          * for all other uses of count in other wait guards.          */       	/** 判断队列是否已经满了 */         while (count.get() == capacity) {           	/** 调用添加元素锁的Condition的await方法进入等待队列进行等待,并且释放锁 */             notFull.await();         }       /** 设置尾节点的下一个节点为新创建节点     		* 将新创建节点设置为尾节点       	*/         enqueue(node);       	/** 调用getAndIncrement方法,先获取count数量,在将count队列元素加一 */         c = count.getAndIncrement();       	/** 判断当前元素小于队列最大数量则唤醒等待线程继续放入元素 */         if (c + 1 < capacity)             notFull.signal();     } finally {       	/** 释放锁 */         putLock.unlock();     }   	/** 如果队列之前为空的话,则调用signalNotEmpty方法唤醒之前等待消费的线程进行消费 */     if (c == 0)         signalNotEmpty(); }static class Node {     E item; 		/** 指向下一个节点 */     Node next;      Node(E x) { item = x; } }private void enqueue(Node node) {     // assert putLock.isHeldByCurrentThread();     // assert last.next == null;   	/** 设置尾节点的下一个节点为新创建节点     	* 将新创建节点设置为尾节点       */     last = last.next = node; }private void signalNotEmpty() {     final ReentrantLock takeLock = this.takeLock;     takeLock.lock();     try {       	/** 唤醒阻塞的消费线程 */         notEmpty.signal();     } finally {         takeLock.unlock();     } }四、take方法public E take() throws InterruptedException {     E x;     int c = -1;   	/** 获取队列中元素数量 */     final AtomicInteger count = this.count;   	/** 获取元素出队锁 */     final ReentrantLock takeLock = this.takeLock;   	/** 加一个可以被中断的锁,保证同一时间只有一个线程可以添加数据     	* 如果加锁线程被中断了,此时加锁会失败,抛出一个线程中断的异常出来       */     takeLock.lockInterruptibly();     try {       	         while (count.get() == 0) {             notEmpty.await();         }       	/** 获取第一个元素 */         x = dequeue();       	/** 调用getAndIncrement方法,先获取count数量,在将count队列元素加一 */         c = count.getAndDecrement();         if (c > 1)           	/** 如果当前队列数量大于1则进行唤醒其他等待消费线程 */             notEmpty.signal();     } finally {       	/** 释放锁 */         takeLock.unlock();     }   	/** 判断队列之前是否已经满了,满了说明可能有有线程在等待     	* 则调用signalNotFull唤醒等待线程       */     if (c == capacity)         signalNotFull();     return x; }private E dequeue() {     // assert takeLock.isHeldByCurrentThread();     // assert head.item == null;     Node h = head;   	/** 获取头节点下一个元素,因为头节点一般为空,忽略 */     Node first = h.next;   	/** 将当前头节点的下一个元素指向自己,后续会gc回收掉 */     h.next = h; // help GC   	/** 在将下一个元素设置为头节点 */     head = first;   	/** 获取数据 */     E x = first.item;   	/** 将新的头节点元素设置为空,保证头节点元素一直为空 */     first.item = null;   	/** 返回数据 */     return x; }private void signalNotFull() {     final ReentrantLock putLock = this.putLock;     putLock.lock();     try {         notFull.signal();     } finally {         putLock.unlock();     } }五、iterator方法public Iterator iterator() {     return new Itr(); }Itr() {   	/** 将队列中获取元素和添加元素的锁进行加锁 */     fullyLock();     try {         current = head.next;         if (current != null)             currentElement = current.item;     } finally {       	/** 对获取元素锁和添加元素锁进行释放 */         fullyUnlock();     } }public E next() {   	/** 将队列中获取元素和添加元素的锁进行加锁 */     fullyLock();     try {         if (current == null)             throw new NoSuchElementException();         E x = currentElement;         lastRet = current;       	/** 获取下一个元素 */         current = nextNode(current);         currentElement = (current == null) ? null : current.item;       	/** 返回元素 */         return x;     } finally {       	/** 对获取元素锁和添加元素锁进行释放 */         fullyUnlock();     } }void fullyLock() {     putLock.lock();     takeLock.lock(); }void fullyUnlock() {     takeLock.unlock();     putLock.unlock(); }private Node nextNode(Node p) {     for (;;) {         Node s = p.next;         if (s == p)             return head.next;         if (s == null || s.item != null)             return s;         p = s;     } }

修修补补又一年篇三装修五年过去我才发现自己被坑了这是我修修补补的第三篇了,这并不是一篇营销号文章,这也不是一篇标题党,我,确实在装修五年后,才发现自己被坑了本文说白了就是一个记录如何安装网口插座与双控开关的记录就算你目前没有安装我发现一个牛X的配方篇十九我参考了哈根达斯钟薛高写下这个配方今天夏天好像真的是特别热,东北都日常30度了,雪糕那自然是日常必备的清凉美食了不过确实今年雪糕确实涨价比较严重,连央视都报道了雪糕起步价涨至2元,工资要是有这样翻倍的涨幅,我也就开百元智能摄像头进入2K时代360智能摄像机小水滴2K版摄像头作为智能家居的排头兵,出现的非常早。早期的非智能摄像头只能解决能看到的问题,产品也特别工业化,说白了就是难用。智能摄像头的出现让好用成为现实,随时随地的方便查看让小白用户也可全新马自达MXx,6s内破百前些日子,五菱宏光MINIEV将推敞篷版车型闹得沸沸扬扬,很多人认为这是敞篷汽车距离我们最近的一次。只是五菱宏光MINIEV敞篷版的上市时间还没敲定,也不知道上市后的定价情况,更重十万级紧凑型车怎么选?伊兰特对比轩逸,谁更能打?如果手握1015万的预算,你会如何选车呢?小编认为,这个价格区间里选择一辆代步工具,紧凑型车是值得考虑的。紧凑型车有着比小型车更大的车内空间,并且在日常用车(包括不同用户的驾驶泊车10万级城市代步车怎么选?省油又耐用,选这两款绝对不亏说到城市代步车,最重要的是什么?那无疑是省油耐用好停车便宜。那如果预算只有10万元,该如何进行选择呢?作为口碑较好的两款平民神车威驰和飞度,它们凭借着优秀的产品力和耐用性深受消费者斯莫格收款ForevalaL20全指向智能降噪领夹麦克风上市!售价199元斯莫格收款ForevalaL20全指向智能降噪领夹麦克风,售价199元,360全指向拾音,设有200Hz一下低频滤波开关,智能降噪,智能运放芯片,增益调节,手机相机拾音一键切换,远美剧AllRise第2季采用27台BMPCC6K拍摄美剧全体起立AllRise(前名法庭内外Courthouse)讲述在洛杉矶的法庭上,法官检察官辩护人法警文员警察及陪审员等人的生活。该剧第二季在疫情期间拍摄中使用了27台PockeATEM现场制作工作流程助力HellaMegaTour巡演BlackmagicDesign今日发布消息称,以GreenDayFallOutBoy和Weezer为主角的HellaMegaTour巡回演出采用BlackmagicDesign采A24影片绿衣骑士采用DaVinciResolveStudio调色BlackmagicDesign今日发布消息称,A24影片绿衣骑士的调色由FotoKem调色师AlastorArnold使用DaVinciResolveStudio完成。影片拍摄由Ultimatte12助力ButcherBirdStudios扩展虚拟制作流程BlackmagicDesign今日发布消息位于美国格伦代尔的制作公司ButcherBirdStudios将Ultimatte12纳入其工作室的制作流程当中,实现实时虚拟制作和录制
新能源汽车消费维权案例1产品质量问题案例据央视网,中国消费者协会公布2021年全国消协组织受理投诉情况分析,并同期发布了部分典型案例和解决建议。其中,新能源汽车举证难维权难是中消协公布的典型案例之一。例小鹏汽车回应修改道路救援条款避免歧义,非质量问题救援将收费Tech星球3月24日消息,针对网友反映的小鹏汽车修改道路救援条款问题,小鹏汽车回应称,这是为了避免歧义而进行的优化。小鹏汽车客服表示,删除服务介绍中不限次数不限里程的表述,是为避买新能源车,怎么选?注意啥?受油价持续上涨平日限号出行等因素影响,不少有意购车者将目光由燃油车投向了新能源汽车。购买新能源汽车需要注意什么?记者采访了从事新能源汽车销售多年的李宏涛,请他为市民做解答。油混插电五菱宏光宣布旗下新能源车型涨价4中华网财经3月24日讯,近日,稳坐新能源汽车销量冠军的神车五菱宏光宣布涨价。据悉,五菱汽车旗下五菱宏光MINIEV系列,其在2021年全年销量426452台,一举问鼎新能源年度销冠为什么谷歌卫星地图水平在全球遥遥领先?我国何时能赶上地图早已是人类社会不可或缺的工具,涉及军事国防国土开发经济发展等国计民生的方方面面。尤其是现代社会,出门旅行开车导航网络购物生活消费等,更是难以离开电子地图的帮助。其中,相比平面地发布会扎堆出场,智能门锁内卷继续阳春三月,发布会纷至沓来,全屋智能霸屏满场。3月16日,华为终端召开2022年华为全屋智能及全场景新品春季发布会,3月17日,智能家居玩家云米科技也紧随其后召开2022春季战略新品会不会选择新能源呢前两天,我在网上看到了这么一个问题,挺有意思的。达到什么条件,你会抛弃燃油车,选择新能源车,新能源车是不是该淘汰传统燃油车呢?你们觉得呢?打在弹幕里告诉我。其实这个提问,天然就预设商务部多举措支持服务业发展引导互联网平台企业下调餐饮业商户服务费标准每经记者张怀水每经编辑陈星服务业作为我国经济的重要增长极和吸收外资的主引擎,将迎来更多支持举措。3月24日,商务部召开例行新闻发布会,商务部新闻发言人束珏婷表示,按照党中央国务院决电脑摄像头被黑客控制怎么办?有这5点可以来避免你会在电脑上把摄像头用胶布给贴住吗?现在的隐私问题是越来越被人们所重视。特别是一些有摄像头的设备更是被广泛关注。比如笔记本电脑。经常会看到一些人用胶带把摄像头给遮挡起来。而且用的还天玑1050发布,台积电6nm工艺,首次支持5G毫米波最近真的是捅了芯片窝了,近期已经有多款芯片发布了,如天玑1300骁龙7Gen1骁龙8Gen1。今日联发科又宣布推出旗下首款,支持5G毫米波的移动平台天玑1050芯片。先来看看芯片的首发!讯飞智能办公本Air使用体验!墨水屏里的iPadmini,强Icarrytheuniversewithme。我将宇宙随身携带讯飞在智能办公本领域一直都是行业领先,此前已陆续上市X1X2T1T2等高端商务和入门商务本,商场反响一直不错,刚刚上