专业的JAVA编程教程与资源

网站首页 > java教程 正文

「不得不看」Java并发编程一(java并发编程之美)

temp10 2024-10-13 09:30:51 java教程 22 ℃ 0 评论

明天的你会感谢今天努力的你

举手之劳,加个关注

「不得不看」Java并发编程一(java并发编程之美)

简介

一直想着对java.util.concurrent (JUC) 进行一次详细的研究,自己也整理了一些相关的知识,却始终没有去阅读源码相关的东西,所以最近想去看一看 JUC 相关的源码,也去看了 “梧留柒” 的博客,里面比较详细的介绍了JUC 中的接口和实现类的源码,所以打算通过博客来记录下相关的知识以此来反复学习。


我们来看下包结构(基于JDK7)



?


?


大致我们可以分为


1. Aomtic 原子数据类型


这部分都被放在java.util.concurrent.atomic这个包里面,实现了原子化操作的数据类型,包括 Boolean, Integer, Long, 和Referrence这四种类型以及这四种类型的数组类型。


2. 锁


这部分都被放在java.util.concurrent.lock这个包里面,实现了并发操作中的几种类型的锁


3. java 并发集合


这部分实现的数据结构主要有List, Queue和Map。


4. 阻塞队列/线程池


Queue 队列


Callable 被执行的任务


Executor 执行任务


Future 异步提交任务的返回数据


Completion 异步非阻塞


5. 并发工具类


这部分主要是对线程集合的管理的实现,有CyclicBarrier, CountDownLatch,Exchanger等一些类


?Aomic数据类型有四种类型:AomicBoolean, AomicInteger, AomicLong, 和AomicReferrence(针对Object的)以及它们的数组类型,

还有一个特殊的AomicStampedReferrence,它不是AomicReferrence的子类,而是利用AomicReferrence实现的一个储存引用和Integer组的扩展类


首先,所有原子操作都是依赖于sun.misc.Unsafe这个类,这个类底层是由C++实现的,利用指针来实现数据操作


关于CAS

一种无锁机制,比较并交换, 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无 论哪种情况,它都会在 CAS 指令之前返回该位置的值。CAS 有效地说明了“我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可”


好处:操作系统级别的支持,效率更高,无锁机制,降低线程的等待,实际上是把这个任务丢给了操作系统来做。


这个理论是整个java.util.concurrent包的基础。


关于sun.misc.Unsafe


几个疑问

1)四个基本类型的compareAndSet和weakCompareAndSet实现是一样的?

2)AtomicLong的set方法非线程安全的,为啥?并非线程不全,而是对于Long的Updater,会有VM_SUPPORTS_LONG_CAS,如果JVM的long操作是原子化的,会采用无锁的CAS来更新,如果不支持就会使用带锁的方式来更新。


AtomicXXXX四个数值类型

1. value成员都是volatile

2. 基本方法get/set

3. compareAndSet

weakCompareAndSet,

lazySet: 使用Unsafe按照顺序更新参考Unsafe的C++实现)

getAndSet:取当前值,使用当前值和准备更新的值做CAS

4. 对于Long和Integer

getAndIncrement/incrementAndGet
getAndDecrement/decrementAndGet
getAndAdd/addAndGet

三组方法都和getAndSet,取当前值,加减之得到准备更新的值,再做CAS,/左右的区别在于返回的是当前值还是更新值。


关于数组

1. 没有Boolean的Array,可以用Integer代替,底层实现完全一致,毕竟AtomicBoolean底层就是用Integer实现

2. 数组变量volatile没有意义,因此set/get就需要Unsafe来做了,方法构成与上面一致,但是多了一个index来指定操作数组中的哪一个元素。


关于FieldUpdater

1) 利用反射原理,实现对一个类的某个字段的原子化更新,该字段类型必须和Updater要求的一致,例如如果使用 AtomicIntegerFieldUpdater,字段必须是Integer类型,而且必须有volatile限定符。Updater的可以调用的方 法和数字类型完全一致,额外增加一个该类型的对象为参数,updater就会更新该对象的那个字段了。

2) Updater本身为抽象类,但有一个私有化的实现,利用门面模式,在抽象类中使用静态方法创建实现


AtomicMarkableReference/AtomicStampedReference

前者ReferenceBooleanPair类型的AtomicReference,ReferenceBooleanPair表示一个对象和boolean标记的pair

前者ReferenceIntegerPair类型的AtomicReference,ReferenceBooleanPair表示一个对象和Integer标记的pair

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表