学习笔记:java并发编程学习之初识Concurrent
一、初识Concurrent
第一次看见concurrent的使用是在同事写的一个抽取系统代码里,当时这部分代码没有完成,有许多的问题,另一个同事接手了这部分代码的功能开发,由于他没有多线程开发的经验,所以我就一起帮着分析。最开始看到这个时很烦燥啊,因为自己接触java时间很短,连synchronized都不知道怎么用呢,突然发现有这么个复杂的东西。当时就只好开始学习吧,毕竟是使用嘛,第一目的就是了解清楚这玩意的各个类与方法都干嘛用的,然后看了看同事的代码大概也就清楚了。感觉这和大部分人一样,能用就行。
下面是一段其中的应用
public class VoiceExtractRunnable implements Runnable { @Override
public void run() { // 创建线程池
ExecutorService service = Executors.newCachedThreadPool();
// 声明保存各任务(线程)执行结果的集合
List<Future<VoiceExtractExpertInRuleVO>> futures = new ArrayList<Future<VoiceExtractExpertInRuleVO>>(
rules.size());
// 循环提交任务
for (VoiceExtractExpertInRuleVO ruleVO : rules) {
ruleVO.setExtractParamVO(vo);
futures.add(service.submit(new VoiceRuleCallable(ruleVO)));
} for (Future<VoiceExtractExpertInRuleVO> f : futures) {
try {
VoiceExtractExpertInRuleVO r = f.get();
returnRules.add(r); // 获取任务执行完成后的返回结果
} catch (Exception e) {
logger.error("", e);
}
}
// 所有任务都执行完毕后,关闭线程池
service.shutdown();
} }
看完这个代码(省略了大部分的业务逻辑代码)就能感觉到一个优点,就是线程的执行和结果获取是可以异步的,这样对于开发来说确实是有很大的帮助。代码结构也比较清晰。
但这个时候我主要还是在能用就行的阶段,而且也并不关心concurrent里到底有多少重要的代码。最近在学习JAVA的基础知识,看到线程安全的时候Concurrent开始进入我的视野,这时我才知道它原来是这么丰富,所以才开始一点点的了解。这个过程中也一直感觉到写这些代码的工程师确实厉害,能在实践的过程中总结出这么好的代码,供广大的开发们使用。
二、主要的类
Executor :具体Runnable任务的执行者。
ExecutorService :一个线程池管理者,其实现类有多种,我会介绍一部分。我们能把Runnable,Callable提交到池中让其调度。
Semaphore :一个计数信号量
ReentrantLock :一个可重入的互斥锁定 Lock,功能类似synchronized,但要强大的多。
Future :是与Runnable,Callable进行交互的接口,比如一个线程执行结束后取返回的结果等等,还提供了cancel终止线程。
BlockingQueue :阻塞队列。
CompletionService : ExecutorService的扩展,可以获得线程执行结果的
CountDownLatch :一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
CyclicBarrier :一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点
Future :Future 表示异步计算的结果。
ScheduledExecutorService :一个 ExecutorService,可安排在给定的延迟后运行或定期执行的命令。
上面是一些常用类,参考这个文章,写的比较清楚:http://www.cnblogs.com/aurawing/articles/1887056.html
我个人看了代码后对下面的这些类印象比较深刻:
ConcurrentHashMap:支持并发的hashMap AbstractQueuedSynchronizer:提供了同步锁的基础功能实现,包含独占锁和共享锁
对于ConcurrentHashMap这个类是一种适应于并发场景下的hashMap,是建立在分离锁基础上。其内部结构可以划分为N个段,每个段都有自己的并发锁,这样写入时可以写入不同的段中,从而提高了并发的性能。
参考:http://blog.csdn.net/fw0124/article/details/43308193
AbstractQueuedSynchronizer是Concurrent包中对锁的关键抽象实现,主要是提供了一个state字段用于控制并发,通过控制state的原子状态从而保证多线程时的锁机制。这个类是抽象类,很多的场景实现需要在特定的子类中实现。
参考:
http://www.infoq.com/cn/articles/jdk1.8-abstractqueuedsynchronizer
http://www.infoq.com/cn/articles/java8-abstractqueuedsynchronizer
三、学习到的一些知识点
这几天在看源代码中也不断的在网上查找各种资料,还是学到了不少东西。
分拆锁(lock spliting)就是若原先的程序中多处逻辑都采用同一个锁,但各个逻辑之间又相互独立,就可以拆(Spliting)为使用多个锁,每个锁守护不同的逻辑。
分拆锁有时候可以被扩展,分成可大可小加锁块的集合,并且它们归属于相互独立的对象,这样的情况就是分离锁(lock striping)。(摘自《Java并发编程实践》)
对于分离锁有个更好些的解释:分拆锁有时候可以被扩展,分成若干加锁块的集合,并且它们归属于相互独立的对象,这样的情况就是分离锁。例如,ConcurrentHashMap 的实现使用了一个包含 16 个锁的数组,每一个锁都守护 HashMap 的 1/16 。假设 Hash 值均匀分布,这将会把对于锁的请求减少到约为原来的 1/16 。这项技术使得 ConcurrentHashMap 能够支持 16 个的并发 Writer 。当多处理器系统的大负荷访问需要更好的并发性时,锁的数量还可以增加。——摘自developerworks
sun.misc.Unsafe 是一个封装了很多底层操作的类,但是网上没找到太多的资料,但在Concurrent包中用的比较多,最为关键的是其提供的方法compareAndSwap之类的方法是原子的,可以不用自己加锁。看了Concurrent包中的锁主要是通过这个方法来实现的锁状态管理。
但网上也提到他可以操作内存,也难怪叫Unsafe这名,如果在java代码里随便用的话那Java不就变成和C++差不多了,呵呵。所以除了在JDK里的单元,自己写的代码中不能直接使用这个类。
volatile关键字:这个关键字是要求多线程环境下访问受volatile修改的共享数据时具有可见性。
我确实不知道怎么解释它,推荐两篇不错的文章:
http://www.ibm.com/developerworks/cn/java/j-jtp06197.html
http://www.cnblogs.com/dolphin0520/p/3920373.html
四、小感慨
在看着Concurrent包里的代码时,确实对一些精秒的设计很感叹,比如锁的设计,一种抽象与实现结合的良好设计。里面的许多小细节都体现了技术的功底,反想自己为什么设计不出这样的代码。
我感觉两方面:
1、没有实际的问题要去解决
比如Concurrent这里面的代码针对并发的编程,说实话工作中遇到的不多,一般的情况用用synchronized也是可以解决的,以前在.net里也就用用lock关键字。delphi用的时候也简单。所以没有一个好的工作场景让你去解决这些问题,说实话想都想不到。
2、基础不扎实
其实看了许多代码都是些基础应用,你说流、文件、并发这些东西都是计算机里都要面对的问题,只要掌握了这些知识,其实在实际遇到问题的时候就可以用上了。否则就会当作难题用一些其他方法规避掉,反而失去了写出更好代码的机会,时间长了就变的平庸
以后还是要多多努力学习基础,这一段时间以来我觉得自己可以在编程上有更多的收获,或许我真的能写代码到50岁,至少我觉得50岁的时候还是可以跟上时代,写出优秀的代码。
学习笔记:java并发编程学习之初识Concurrent的更多相关文章
- Java并发编程学习前期知识下篇
Java并发编程学习前期知识下篇 通过上一篇<Java并发编程学习前期知识上篇>我们知道了在Java并发中的可见性是什么?volatile的定义以及JMM的定义.我们先来看看几个大厂真实的 ...
- Java并发编程学习笔记
Java编程思想,并发编程学习笔记. 一.基本的线程机制 1.定义任务:Runnable接口 线程可以驱动任务,因此需要一种描述任务的方式,这可以由Runnable接口来提供.要想定义任务,只需实现R ...
- Java并发编程学习路线(转)
以前特地学过并发编程,但是没怎么学进去,不太喜欢.最近发现,作为一个资深工程师,却没有完整深入系统的学习过,而反是现在的BAT大并发是必须的,感觉甚是惭愧. 故找了一片学习文章,如下,准备集中一段时间 ...
- Java并发编程学习路线
一年前由于工作需要从微软技术栈入坑Java,并陆陆续续做了一个Java后台项目,目前在搞Scala+Java混合的后台开发,一直觉得并发编程是所有后台工程师的基本功,所以也学习了小一年Java的并发工 ...
- Java并发指南开篇:Java并发编程学习大纲
Java并发编程一直是Java程序员必须懂但又是很难懂的技术内容. 这里不仅仅是指使用简单的多线程编程,或者使用juc的某个类.当然这些都是并发编程的基本知识,除了使用这些工具以外,Java并发编程中 ...
- Java并发编程学习:volatile关键字解析
转载:https://www.cnblogs.com/dolphin0520/p/3920373.html 写的非常棒,好东西要分享一下 Java并发编程:volatile关键字解析 volatile ...
- [Todo] Java并发编程学习
有两个系列的博文,交替着可以看看: 1. Java并发编程与技术内幕 http://blog.csdn.net/Evankaka/article/details/51866242 2. [Java并发 ...
- (转)《深入理解java虚拟机》学习笔记10——并发编程(二)
Java的并发编程是依赖虚拟机内存模型的三个特性实现的: (1).原子性(Atomicity): 原子性是指不可再分的最小操作指令,即单条机器指令,原子性操作任意时刻只能有一个线程,因此是线程安全的. ...
- Java并发编程学习笔记 深入理解volatile关键字的作用
引言:以前只是看过介绍volatile的文章,对其的理解也只是停留在理论的层面上,由于最近在项目当中用到了关于并发方面的技术,所以下定决心深入研究一下java并发方面的知识.网上关于volatile的 ...
随机推荐
- 用.net 发送邮件
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.N ...
- 【Java EE 学习 71 上】【数据采集系统第三天】【增加页面】【增加问题】【编辑页面,编辑问题】
增加页面和编辑页面.增加问题和编辑问题的页面使用的都是相同的页面,最后调用的方法是saveOrUpdate方法,所以只说一个就可以了. 一.增加页面 比较简单,略.流程如下: 单击“增加页”超链接-& ...
- 【Java并发系列02】Object的wait()、notify()、notifyAll()方法使用
一.前言 对于并发编程而言,除了Thread以外,对Object对象的wati和notify对象也应该深入了解其用法,虽然知识点不多. 二.线程安全基本知识 首先应该记住以下基本点,先背下来也无妨: ...
- Oracle sql连接
inner-join left-outer-join right-outer-join full- ...
- 【转载】 wpf无边框的方法以及拖拽的问题
今天在做wpf程序的时候遇到了一个制作无边框的窗体并且有透明圆角的问题,我把解决的过程写下来,和大家学习 正常窗体必须把WindowStyle="None"这个属性加上去,但是加上 ...
- Android Studio 引用 gson-2.6.2-sources
1.拷贝到libs下
- 学习微信小程序之css11内外边距集合
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- android Studio 百度KEY获得发布版 SHA1 的方法
看图说话 build-->Generate Signed APK... create new(看不懂单词意思的同胞可以参考这个网址http://www.cnblogs.com/why168888 ...
- 用vue2 +vue-router2 + es6 +webpack 高仿饿了么app(干货满满)
#高仿饿了么app商家详情 (vue2 +vue-router2 + es6 +webpack ) ##demo [demo 地址](http://liangxiaojuan.github.io/ ...
- VirusAnti_didiwei使用说明
前言 前段时间说要写的一个专杀框架敌敌畏,后改为强撸敌敌畏,以彰显样本查杀时的气势,现在第一版已经完成了,如下图所示,使用的时候强烈建议控制台使用放大模式,这样就可以看见我花了半天才画好了logo , ...