学习笔记: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的 ...
随机推荐
- iOS打包ipa给客户测试流程
IOS项目开发的过程中经常会用到一个测试的问题,特别是外包的项目,客户拿了那么多钱,看不到产品时时的进度说不过去,而且UI和功能是否和符合用户需求这个很重要,需要客户的认同. 所以就需要时时给开发中的 ...
- 使用AFNetWorking上传图片
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; NSString *string ...
- Python 学习拾遗
该博文主要适应于python2.7,并没有对py3进行测试. 主要记录学习python过程中容易出现的一些小问题.小错误,相信能给你启发. 1.剔除一个字符串中的所有空格(假设该字符串是s) &quo ...
- Cocos2d-x 生成真正的随机数
关于随机数 cocos2d-x 定义了一个宏 CCRANDOM_0_1 生成的是 [0, 1] 之间的值 因此,要生成 [0-100] 之间的数 CCRANDOM_0_1 * 100 生成 [ ...
- UVA 12300 Smallest Regular Polygon(正多边形)
题意:给出两点,求经过这两点的正n边形的最小面积 题解:这两点一定是最长的弦,我们设正多边形中点c,找到c到每个点的距离(都相同) 我们知道那个等腰三角形的底与每个角度就使用余弦定理 #include ...
- Linux usual cmd
日常工作时常需要用到,在此备份一下: <1> top命令 第一行:当前系统时间为23:31:59,系统已经运行了127天又19小时47分钟,当前系统只要一个用户即root,load ave ...
- How to configure security of ActiveMQ ?
Terms {activemq.home}: The ActiveMQ installation folder. How to configure ActiveMQ to use JAAS Authe ...
- var a=b=c=1; 和 var a=1, b=2, c=3; 的区别。
function test(){ var a=b=c=1; var a=1, b=2,c=3; } 1中b\c 为全局变量, a为私量 2中a\b\c为私量
- 洛谷 P1827 美国血统 American Heritage Label:字符串Water
题目描述 农夫约翰非常认真地对待他的奶牛们的血统.然而他不是一个真正优秀的记帐员.他把他的奶牛 们的家谱作成二叉树,并且把二叉树以更线性的“树的中序遍历”和“树的前序遍历”的符号加以记录而 不是用图形 ...
- Vim 插入递增列
<C-a> ++1 <C-x> --1 安装Plugin 'terryma/vim-multiple-cursors'后 <C-v> 选所有数字 <C ...