聊下java并发包

先从整体上说下

大致分为下面几个包
atomic包
locks 包
线程池&并发集合

并发集合


ConcurrentHashMap

这个集合是建立在HashMap基础上的,可以分jdk1.7和jdk1.8来说
jdk1.7:
由一个个Segment组成,每个Segment里面类似HashMap结构,默认是有16个Segment,此时最多可以允许16个线程并发操作。Segment指定后不可扩容。
jdk1.8:
抛弃了分段锁,结构上与HashMap一致,链表加红黑树

CopyOnWriteArrayList

CopyOnWriteArrayList是一个线程安全ArrayList。
读操作无锁,add操作时采用拷贝一个新数组来操作,读效率很高,但是有可能有脏读

CopyOnWriteArraySet

基于CopyOnWriteArrayList,但是添加的时候得遍历下元素在不在,所以效率低一点
hashset也是添加的时候遍历吗?是的,只不过不是顺序遍历。因为它是基于hashmap实现的,根据hashcode定位到位置后,会判断这个位置有没有元素,有的话key是不是相等,相等则覆盖value

BlockingQueue

这是个接口,实现的有
1.ArrayBlockingQueue 基于数组先进先出,有界
2.LinkedBlockingQueue 基于链表,默认无界(INT最大值),可指定容量
3.PriorityBlockingQueue 无界

lock


AQS

提供基于Lock接口的并发基础类,主要运用CAS实现。
目的:在并发状态下管理被阻塞的线程
作用: 提供一套通用的机制来管理同步状态,阻塞/唤醒线程,管理等待队列等。
方法:acquire()、acquireShared()、release()、releaseShared()、hasWaiters()、cas修改状态及头/尾指针的方法等
核心:等待队列(CLH队列)

CLH队列

1.双向链表
2.结点是对线程的包装,分独占和共享两种类型
3.用前一结点的某一属性表示后一结点的状态
4.自旋方式不断cas插入包含当前线程的结点到尾部

Condition

一般配合lock使用,await()、signal()、signalAll()
Object里面的wait()、notify()、notifyAll()是配合synchronized使用的

ReentrantLock

基于AQS,里面有一个state值,先CAS设置state,如果state!=0,但发现拿锁的是自己则++,获取失败的加到CLH队列尾,内部自旋继续获取锁。
这里可以顺便说下synchronized,它基于monitor对象的进入进出实现,monitor在对象头中,如果被线程持有便处于锁定状态,另外,synchronized同步块时,是显示的用monitorenter和monitorexit两个指令实现同步;而synchronized同步方法时,是隐式的,会取常量池中方法的ACC_SYNCHRONIZED表示是否同步方法,是则获取monitor。早期monitor依赖底层操作系统实现,所以存在用户态到核心态的切换,效率低,但jdk6后做了很多优化,比如偏向锁,轻量锁,锁自旋,锁消除等。

lock与synchronized区别,什么时候用lock

底层原理的区别就是上面说的,至于其它的,lock是接口,synchronized是同步原语;lock需要手动释放,而且lock可以实现公平锁和读写锁;两个都是可重入锁。

atomic


AtomicInteger

里面有一个volatile 修饰的value属性,为了保证值在线程间可见,并发的操作采用CAS,可实现原子递增,
这里也可以看出来,如果一个变量只是volatile修饰是不能实现原子递增的,因为i++涉及2步操作,一个是获取值,一个是赋值。

线程池


有几个关键类要搞清楚
Executor 接口,只有一个execute方法
Executors 封装了一些创建常用线程池的方法
ExecutorService 接口,继承execute,含shutdown、submit、invokeAll等方法
ThreadPoolExecutor,实现ExecutorService,也可用于创建线程池
Future 接口,含cancel、get、isDone等方法

一般常见的线程池如下,可用Executors调用创建
newFixedThreadPool,固定线程数量的
newSingleThreadExecutor ,单个线程的
newCachedThreadPool, 可调节线程数量线程池,有核心线程数量和最大线程数量
newSingleThreadScheduledExecutor, 可执行定时任务的线程池
这几个实现都是调用ThreadPoolExecutor去设置不同的参数。

这里还可以提一下使用异步线程的时候注意try-catch再打个日志, 否则可能造成出现异常又没有日志的情况
private static final ThreadPoolExecutor threadPool = newThreadPoolExecutor(4,10,60,TimeUnit.SECONDS,newLinkedBlockingQueue());

同步&互斥类


CyclicBarrier

可循环利用屏障,有两个构造方法
CyclicBarrier(int parties)和CyclicBarrier(int parties, Runnable barrierAction) 
后者,Runnable参数表示当调用cb.await()的的线程数达到指定数量后,开始执行的方法。
比如new CyclicBarrier(4, “do一起出门”)
有4个同学分别开始准备出门,准备好之后都调用cb.await(),表示达到屏障,达到4个之后,就一起出门。
实现原理:
主要基于ReentrantLock,CyclicBarrier里有一个lock属性。
1.每当线程执行await,内部变量count减1,如果count!= 0,说明有线程还未到屏障处,则在锁条件变量trip上等待。
2.当count == 0时,说明所有线程都已经到屏障处,执行条件变量的signalAll方法唤醒等待的线程

CountDownLatch

倒数的门栓,主要有两个方法countDown()和await()。
一般呢在主线程await(),然后开几个线程去执行一些其它的逻辑,执行完后分别调用countDown(), 每次countDown()数量减1,当数量到0后,便会通知主线程继续执行。
实现原理:
基于AQS,AQS里有一个volatile 修饰的state,每次countDown()时会CAS-1,调用await()会判断state是否为0,不是则等待。

这里可以顺便说下CyclicBarrier和CountDownLatch两者的一个区别:
CyclicBarrier可以重复使用,CountDownLatch不能

Semaphore

信号量,主要有acquire() 和 release() 两个方法。
比如初始有10个信号,new Semaphore(10),然后执行方法的时候先调用acquire() 获取一个信号,
如果有则可以执行,并且剩余信号量减1,没有则等待; 获取了信号的线程执行完之后可以释放信号,释放了剩余信号就加1.
实现原理:
也借助AQS,并有公平和非公平两种方式


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容