摘要:针对高质量多线程并发程序设计时为防死崩等现象的出现,比如使用之前的和等,每每需要考虑性能死锁公平性资源管理以及如何避免线程安全性方面带来的危害等诸多因素,往往会采用一些较为复杂的安全策略,加重了程序员的开发负担。
大家好,最近由于公司的事情不是很多,准备开篇写一写concurrent这一块,因为最近好多面试者对这个都不是很了解,有的是知其然不知其所以然,我写这篇(系列)文章的初衷是为了总结和归纳这一块,如果本文能够对大家带来一定的帮助,那么一定是我莫大的荣耀,好了,话不多说我们开始探秘concurrent吧。
首先从字面意思我们能理解到concurrent是“同时发生的”,在java中自然是用来做并发使用的,这个concurrent 包是java5才提出的,然而经过几个版本的更迭,目前已经是大家都会深入用到,或者是多少会接触到的,其实在java中已经有Thread,Runnable等多线程的实现;我们为什么要用到concurrent包来做呢?下面我将带大家一步一步的了解。
针对高质量Java多线程并发程序设计时,为防死崩等现象的出现,比如使用java之前的wait()、notify()和synchronized等,每每需要考虑性能、死锁、公平性、资源管理以及如何避免线程安全性方面带来的危害等诸多因素,往往会采用一些较为复杂的安全策略,加重了程序员的开发负担。为了减少甚至是去除咱们这种后顾之忧, Doug Lea为大家推出了这个解决方案,让众多java开发者如沐春风。
在java8中concurrent一共有21个接口、38个类其中包括抽象类和内部类、1个枚举类、6种异常方式,当然这个数字都不重要,大家在看api的时候只会找自己关注的部分。
1. BlockingDequeBlockingDeque继承自BlockingQueue和 Deque ;BlockingQueue也是java.util.concurrent包下面的一个接口,而Deque则属于java.util。
来自官方的一段说明是,该接口定义了在deque两端访问元素的方法。提供了插入、删除和检查元素的方法。这些方法中的每个存在两种形式:一个抛出一个异常,如果操作失败,另一个返回一个特殊的值(无论是null或false,取决于操作)。插入操作的后一种形式是专为使用有容量限制deque实现;在大多数实现中,插入操作不会失败。
这个队列的特性其实是保证了先进先出的原则,与列表接口不同,此接口不提供对元素索引访问的支持。在实现中Deque不强制禁止空值,但是不推荐这样去做。
2. BlockingQueue这个接口和上面一个长得有点像,但不要混淆了,干妹妹和干妹妹还不是一个意思呢(好污...)。BlockingQueue是用来对不同操作进行不同处理的(你这不是废话么...)BlockingQueue一共有四种处理形式,分别为 Throws exception、 Special value、 Blocks(不是打篮球的盖帽)、 Times out;其实核心意思就是不满足的就抛出异常、根据操作返回一个特定值true或false、让当前线程执行到成功为止,最后就是设定一个超时时间,以免第三步一直不成功。
下面是官方给出的一个例子,大家可以感受下:
class Producer implements Runnable { private final BlockingQueue queue; Producer(BlockingQueue q) { queue = q; } public void run() { try { while (true) { queue.put(produce()); } } catch (InterruptedException ex) { ... handle ...} } Object produce() { ... } } class Consumer implements Runnable { private final BlockingQueue queue; Consumer(BlockingQueue q) { queue = q; } public void run() { try { while (true) { consume(queue.take()); } } catch (InterruptedException ex) { ... handle ...} } void consume(Object x) { ... } } class Setup { void main() { BlockingQueue q = new SomeQueueImplementation(); Producer p = new Producer(q); Consumer c1 = new Consumer(q); Consumer c2 = new Consumer(q); new Thread(p).start(); new Thread(c1).start(); new Thread(c2).start(); } }
好啦,本篇文章就先到这里了,我们后面会继续讲这个神奇的concurrent包,大家有兴趣的话可以关注一下本文。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/65029.html
摘要:通过方法提交一个任务,并且通过对象来获得结果。对象可以取消运行任务,设置等待时间,获取任务状态,最终获得任务结果。类似于,但是并不会有返回结果和异常信息。由两个阶段所触发的,没有保证的结果用于依赖阶段的计算。 本系列关于concurrent的代码示例,是被我分割成了小部分,在系列文章结束以后,我会将较为完整的代码上传,在写的过程中我会参考官方API以及其他牛人的见解,大家有不同的看法可...
摘要:并发和并行并发和并行是两个非常容易被混淆的概念。并发说的是在一个时间段内,多件事情在这个时间段内交替执行。并行说的是多件事情在同一个时刻同事发生。由于线程池是一个线程,得不到执行,而被饿死,最终导致了程序死锁的现象。 同步(Synchronous)和异步(Asynchronous) 同步和异步通常来形容一次方法调用,同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为...
摘要:所有示例代码请见下载于基本概念并发同时拥有两个或者多个线程,如果程序在单核处理器上运行多个线程将交替地换入或者换出内存这些线程是同时存在的,每个线程都处于执行过程中的某个状态,如果运行在多核处理器上此时,程序中的每个线程都 所有示例代码,请见/下载于 https://github.com/Wasabi1234... showImg(https://upload-images.jians...
摘要:有三种状态运行关闭终止。类类,提供了一系列工厂方法用于创建线程池,返回的线程池都实现了接口。线程池的大小一旦达到最大值就会保持不变,在提交新任务,任务将会进入等待队列中等待。此线程池支持定时以及周期性执行任务的需求。 这是java高并发系列第19篇文章。 本文主要内容 介绍Executor框架相关内容 介绍Executor 介绍ExecutorService 介绍线程池ThreadP...
摘要:方法由两个参数,表示期望的值,表示要给设置的新值。操作包含三个操作数内存位置预期原值和新值。如果处的值尚未同时更改,则操作成功。中就使用了这样的操作。上面操作还有一点是将事务范围缩小了,也提升了系统并发处理的性能。 这是java高并发系列第21篇文章。 本文主要内容 从网站计数器实现中一步步引出CAS操作 介绍java中的CAS及CAS可能存在的问题 悲观锁和乐观锁的一些介绍及数据库...
阅读 1262·2021-11-25 09:43
阅读 721·2021-11-18 10:02
阅读 2836·2021-09-07 09:59
阅读 2731·2021-08-30 09:44
阅读 2903·2019-08-30 13:17
阅读 2271·2019-08-29 12:17
阅读 1659·2019-08-28 17:57
阅读 1265·2019-08-26 14:04