深入理解JUC(java.util.concurrent)

原创
2019/04/21 13:03
阅读数 273

Concurrent下的核心类

  1. Executor:具有runnable任务的执行者
  2. ExecutorService:一个线程池管理者,实现类有多种,能把runnable,callable提交到线程池中
  3. Semaphore:一个计数信号量
  4. ReentranLock:一个可重入的互斥锁定Lock,功能类似于synchronized锁,功能更强大写
  5. Future: 表示异步计算的结果
  6. BlockQueue:阻塞队列
  7. CompletionService:ExecutorService的扩展类,可以获得线程的执行结果
  8. CountDownLatch:一个同步辅助类,在完成一组正在其他线程执行的操作前,它允许一个或多个线程等待
  9. CyclicBarrier:一个同步辅助类,它允许一组线程互相等待,直到达到某个公共屏障值。

 

 

Concurrent如何防止死锁

核心的接口:Lock和ReetranLock

 

JUC下几个常用的锁处理类:

ReentranLock:互斥锁

ReadWriteLock:读写锁

Condition:控制队列

LockSupport:阻塞原语

Semaphore:信号量

CountDownLatch:闭锁

CyclicBarrier:栅栏

Exchange:交换机

CompletableFuture:线程回调

 

 

由于synchronized可以保证数据安全,但是所有的线程只能共享一把锁,所以JUC中做了各类工具的引用

 

重新认识ConcurrentHashMap和CopyOnWriteArrayList

ConcurrentHashMap

 

ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成。

Segment是一种可重入锁ReentrantLock,在ConcurrentHashMap里扮演锁的角色,HashEntry则用于存储键值对数据。

一个ConcurrentHashMap里包含一个Segment数组,Segment的结构和HashMap类似,是一种数组和链表结构, 一个Segment里包含一个HashEntry数组,每个HashEntry是一个链表结构的元素, 每个Segment守护者一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得它对应的Segment锁。

 

 

CopyOnWriteArrayList

这是一个ArrayList的线程安全的变体,其原理大概可以通俗的理解为:初始化的时候只有一个容器,很常一段时间,这个容器数据、数量等没有发生变化的时候,大家(多个线程),都是读取(假设这段时间里只发生读取的操作)同一个容器中的数据,所以这样大家读到的数据都是唯一、一致、安全的.

但是后来有人往里面增加了一个数据,这个时候CopyOnWriteArrayList 底层实现添加的原理:

  1. 先通过lock.lock获取到锁,保证一次只有一个线程添加元素
  2. 然后copy出一个容器(可以简称副本),这个副本的长度为原数组的length+1
  3. 再往新的容器里添加这个新的数据,最后把新的容器的引用地址赋值给了之前那个旧的的容器地址

 

CopyOnWriteArrayList最大的问题是不能保证数据的实时一致性,因为若是有线程在进行写操作的时候,其他读操作的线程仍是读老的list,不能保证立马看到数据的改变

展开阅读全文
打赏
0
3 收藏
分享
加载中
更多评论
打赏
0 评论
3 收藏
0
分享
返回顶部
顶部