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

阻塞队列ArrayBlockingQueue的实现原理浅析

  阻塞队列介绍
  阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。 阻塞队列例子    public static void main(String[] args) {         BlockingQueue bq = new ArrayBlockingQueue(10);         new Thread(new Runnable() {             @Override             public void run() {                 try {                     int i = 0;                     while(true) {                         i++;                         System.out.println("放入:"+i);                         bq.put(i+""+new Date());                         Thread.sleep(1000);                     }                 } catch (InterruptedException e) {                     // TODO Auto-generated catch block                     e.printStackTrace();                 }             }         }).start();         new Thread(new Runnable() {             @Override             public void run() {                 try {                     while(true) {                         String i =bq.take();                         System.out.println("取出:"+i);                         Thread.sleep(2000);                     }                 } catch (InterruptedException e) {                     // TODO Auto-generated catch block                     e.printStackTrace();                 }             }         }).start();     } }阻塞队列原理
  我们这里简要分析一下上面的程序是如何实现一个线程(生产者)放内容,等队列满了就暂停等待,直到队列有空位就继续放,另一个线程(消费者)取内容,队列为空就暂停等待,知道到队列有值就继续取。 1、初始化阻塞队列BlockingQueue bq = new ArrayBlockingQueue(10);
  我们这里是初始化长度为10的阻塞队列,点进去看看具体做了啥 public ArrayBlockingQueue(int capacity, boolean fair) {     if (capacity <= 0)        throw new IllegalArgumentException();     //1、初始化一个长度为capacity的数组,这里传的是10     this.items = new Object[capacity];     //2、初始化一个可重入锁     lock = new ReentrantLock(fair);     //3、初始化一个非空Condition     notEmpty = lock.newCondition();     //4、初始化一个非满Condition     notFull =  lock.newCondition(); }
  上面代码简单清晰易懂,第1步初始化一个长度为capacity的数组是指定这个阻塞队列的长度就是10,第2步是初始化一个可重入锁,这个是用于在队列中放数据的时候和取数据的时候做同步的,应为不可能说生产者和消费者同时放数据和取数据,会有并发问题,所以这里需要一个锁来同步,同步生产者和消费者在放数据和取数据的交互过程,生产者和消费者在跟队列放或者取完数据后就可以把锁释放去执行自己的业务逻辑了。
  第3步和第4步是生成了两个Condition,那Condition是干啥的呢,这里简单说下,在使用Lock之前,我们都使用Object 的wait和notify实现同步的。如下代码 synchronize(obj){      obj.wait();//等待 }synchronize(obj){      obj.notify();//唤醒  }
  有了lock后,现在是: lock.lock();  condition.await(); //等待 lock.unlock();lock.lock();  condition.signal(); //唤醒 lock.unlock();
  相比Object更加的灵活。所以可以推测第3步和第4步就是用来在队列空或者满的时候进行阻塞和唤醒的,具体怎么用,我们得继续向下看源码。 2、生产者放数据bq.put(i+""+new Date());
  点进去查看源码 public void put(E e) throws InterruptedException {         //1、检查元素是否是空的         checkNotNull(e);         //2、获取重入锁         final ReentrantLock lock = this.lock;         //3、锁住         lock.lockInterruptibly();         try {             //4、如果队列满了             while (count == items.length)                 //await阻塞当前线程,释放锁                 notFull.await();             //5、如果没有满,则加入到队列中             enqueue(e);         } finally {             //不管如何,最后都需要进行锁的释放             lock.unlock();         }     }
  逻辑还是特别清晰的,关键点就在于如果队列满了,就直接阻塞线程,也就是阻塞了生产者。  notFull.await();
  所以初始化的时候实例化的notFull的作用就是给生产者用的,可以推测,在消费者取走数据后,肯定会调用唤醒的方法。 notFull.signal();
  也可以推测出,如果这里不满,那么执行完 enqueue(e)加入数据到队列中后,肯定会调用消费者线程的唤醒方法。 notEmpty.signal();
  我们进入enqueue(e)方法的源码看看是否如推测一样。 private void enqueue(E x) {        // assert lock.getHoldCount() == 1;        // assert items[putIndex] == null;        //获取队列        final Object[] items = this.items;        //新加入一个值        items[putIndex] = x;        //如果已经加入到最后了,那么下一次从第一位加入,否则在下一个位置加入        if (++putIndex == items.length)            putIndex = 0;        //队列中的数目自增        count++;        //唤醒消费者        notEmpty.signal();     }
  逻辑也很简单,不出所料,最后因为在队列中加入了数据,调用了消费在的Condition进行唤醒。 notEmpty.signal();
  接下来我们再看看消费者怎么消费数据的,如果队列空了会怎么阻塞,其实都可以猜猜到,肯定是先获取锁,然后判断队列是否为空,若为空则阻塞,不为空则从队列中取树,后唤醒生产者,如果生产者本来就没有被阻塞也就不用唤醒。 3、消费者消费数据String i =bq.take();
  我们点进源码去看看  public E take() throws InterruptedException {         //1、获取锁         final ReentrantLock lock = this.lock;         //2、锁住         lock.lockInterruptibly();         try {             //3、如果队列为空,则阻塞消费者             while (count == 0)                 //4、阻塞,这里会释放锁                 notEmpty.await();             //5、如果不为空,这里会取数据             return dequeue();         } finally {             //7、释放锁             lock.unlock();         }     }
  逻辑也很简单,反正一开始只要生成则没有在放数据的过程中,或者已经阻塞,则消费者在第2步骤都可以获得锁进行操作,我们直接看如果不为空dequeue()如何取数据,可以推测,里面取完数据后会进行唤醒生产者的操作,点进去看看。  private E dequeue() {         // assert lock.getHoldCount() == 1;         // assert items[takeIndex] != null;         //获取当前数组         final Object[] items = this.items;         @SuppressWarnings("unchecked")         //取的数据         E x = (E) items[takeIndex];         items[takeIndex] = null;         //下一次就取下一个,但是如果已经到最后了,下一次就取第一个         if (++takeIndex == items.length)             takeIndex = 0;         //队列数据减一         count--;         if (itrs != null)             itrs.elementDequeued();         //唤醒生产者         notFull.signal();         return x;     }
  源码也很简单,逻辑清楚,最后也不出所料调用了唤醒生产者的方法。 notFull.signal();总结
  这大概是我见过JUC中最清晰易懂的源码了。

交易逆转两矿池对比特币现金进行了51攻击据报道,比特币现金在5月15日的硬分叉升级后遭受了51的攻击。在比特币现金进行了硬分叉升级后,攻击者利用更新中的漏洞,将无效交易添加到未处理事务池(MemPool)中。有一消息人士注意啦!今天刚刚硬分叉的Zcash将带来啥?今天早上,李咏妻子哈文在微博发文宣布李咏突然去世的消息,让很多人难以置信,多数人甚至都没听过他得病的消息!没想到再一次听到他的消息,就是告别人世。在感叹生命脆弱的同时,子番也要跟那还在用Windows挖矿?Linux了解一下作为红警里面炸过桥传奇里面挨过刀劲舞团里吹过萧的新时代好青年,Windows系统可以说和大家的生活工作已经是密不可分了。今天跟群里的矿友们聊天,小编就看到一个矿友说装个Window选错WiFi6路由太糟心!这几点要提前看今年路由器最火的话题是什么?就是换WiFi6路由器。相比较传统的WiFi5路由器,WiFi6路由器拥有着更快的网速,更低的延迟,同时负载能力也更强,覆盖能力也更出色一些,越来越多人千元机守门员已将门焊死,红米Note10pro介绍在国人印象里,小米一直是低价高配的存在,人称价格屠夫,正是因为小米公司的伟大,我们今天才能买到有极高性价比的手机。今天我们不谈信仰,来介绍所有千元以上机型中最值得推荐的旗舰芯小金刚硬核品质得多方认可,努比亚小黄人联名款新品火爆来袭近日,努比亚小黄人联名款新品开售的消息在业内引起了广泛关注。作为数码圈第一冲浪选手,我也马不停蹄的追了一波热点,对这款新品及努比亚在充电器方面的实力做了一番了解。而就目前了解来看,一机两网华为全屋智能驱动行业升级革命作为科技巨头,华为给人的第一印象应该是创新实力强悍,善于厚积薄发,不管涉及哪个行业领域都是如此。就目前来看,华为全屋智能的提出标志着华为要向家居业进军。但对于我们来说,全屋智能是一HarmonyOS助力打造新物种,智能学习行业或将迎来新生华为又双叒叕要发布新的HarmonyOS设备新品了!就在今天刚刚曝光的一段预热视频里这个看上去像是平板又不太像的新品,可以说吊足了大家的胃口。说它是平板因为在视频开始的第一个画面来第五届中国建博ampampquot葵花奖ampampquot公布华为全屋智能拿下四大重要奖项2021年7月20日,由中国建博会网易家居建博网广东省家居建材商会主办的第五届葵花奖智能家居评选颁奖盛典于广州举行。因奖项每年会吸引众多智能家居品牌及行业大咖密切关注深度参与,因此矿视界译文Dfinity能让DeFi更去中心化?我们希望人们放弃传统的IT,将所有系统和服务转移到智能合约中,Dfinity的首席科学家DominicWilliams如是说。互联网计算机(TheInternetComputer)矿视界译文Dfinity的互联网计算机将如何集成以太坊互联网计算机的诞生正是受到了以太坊的启发,实现两者之间的互操作性将是互联网计算机的一个早期目标。Dfinity创始人多米尼克威廉姆斯(DominicWilliams)说。早在上周三
新能源汽车市场发展如此迅猛,你是否足够了解?由于当下的限行政策,油价不断上升,新能源汽车未来的发展有着一定市场潜力。看到新能源汽车市场发展如此迅猛,那你是否都是足够了解?今天编辑就给大家简单介绍一下如今市面上主销的几种新能源市值接近万亿,比亚迪蝉联新能源车市场销量冠军随着新能源汽车板块的持续升温,7月的新能源汽车细分市场销量也如期而至。据中国汽车工业协会最新统计的销量数据,7月新能源细分市场中,新能源汽车销量为27。1万辆,再创单月销量历史新高打造全新智慧生活,您需要这10大智能家居系统近几年,随着5G和物联网(IoT)的催化式发展,智能家居所带来的科技感正不断渗透到我们的生活点滴中。从智能门锁智能照明智能安防到智能冰箱体感电视等智能家电,我们居住的空间正变得越来ampampquot苹果今年将举办3次新产品活动9月是iPhone,11月MacBookampampquot苹果苹果秋季发布会苹果发布会彭博社预测,iPad也将通过其他活动公开有预测称,苹果将在今年秋天举行多次新产品活动。彭博社记者马克格曼(markgerman)最近通过新闻稿表示,苹果无钴电池即将进入市场,高能量密度电池需求激增近日,工信部发布了新能源汽车推广应用推荐车型目录(2021年第7批),共有66款新能源乘用车入选。其中搭载了磷酸铁锂电池的车型有30款,三元电池车型有35款。电池供应商依然是宁德时资讯测试里程超1400万公里,百度发布无人车出行服务平台萝卜快跑百度宣布推出无人车出行服务平台萝卜快跑文懂车帝原创魏微懂车帝原创行业8月18日,百度世界大会2021开幕。百度创始人董事长兼首席执行官李彦宏与百度各业务板块负责人以线上直播的形式,这家和创空间获得江苏省科技厅认可近日,江苏省科技厅发文为推动众创空间健康发展,加快培育经济新动能,根据江苏省众创空间备案办法(试行)(苏科技规2019207号)有关要求,在地方评审推荐省级审核的基础上,经研究,决哪些上市公司布局了Filecoin赛道?就2021年,大的上市公司就有A股上市公司新元科技纳斯达克上市公司第九城市美股上市公司码链新大陆有限公司香港上市公司时代环球集团控股有限公司宣布进入Filecoin赛道,下面分别介高通高性能调度器进一步解锁WiFi连接体验高通希望通过网络调度器的高性能调度,进一步激发WiFi6的潜力,提升连接速度和稳定性,高通前段时间发布的WiFi6白皮书中就很好地展示了高性能网络调度器对于提升WiFi6网络体验的国外科学家成功唤醒植物人,为何会引发亲属不满?这是一个重要的临床和道德问题随着科学的发展进步,患者或许仍有一定的希望,我们是否有权剥夺其生命?2016年,在法国里昂的一所医院,一名男子流下了一滴眼泪。一台红外摄像机记录了这个时四川比特币矿场一停,标志着我国彻底退出比特币挖矿的大舞台今天,让我们谈谈为什么我们在BTC的监督之下继续增加BTC的地位。关键是这两件事,它们限制了BTC的货币挖掘和交易。一周后,央行提醒并与所有银行进行了交谈严禁所有机构与我进行数字货