自学内容网 自学内容网

多线程小知识

一. CAS

CAS (Compare and Swap, 比较并交换) 是一种无锁编程技术, 用于实现多线程环境下对共享资源的线程安全访问. CAS 的核心思想是: 只有当内存中的值与预期值相匹配时, 才会将内存中的值更新为新值.

寄存器1中存放原值, 寄存器2中存放新值. 现在要将内存中的原值更新为新值. CAS会先比较内存中的值和寄存器1中的值, 如果相等, 则交换内存和寄存器2中的值 (相当于把内存中的值更新).

 CAS 最核心的优点在于只通过一个CPU指令就完成了上述操作. 我们知道, 一个CPU指令, 一定是原子的, 那么就一定是线程安全的. java也基于CAS实现了许多"原子类", 这些原子类的 ++ / -- 操作都是原子的, 没有线程安全问题.

我们可以以AtomicInteger为例, 看一下其内部是怎么利用CAS实现原子操作的.

 这里的value就是内存中的数据, oldValue就是寄存器1中的数据, 表示内存中数据的原值.  CAS里对比 oldValue 和 value 是否相同, 如果相同, 就意味着在赋值操作(oldValue == value) 和比较操作之间没有其他线程插入进来 (如果不相同, 就意味着有其他线程插入进来把内存中value的值改了). 如果没有线程插入, 那么我们就可以把内存中的value更新, 如果有其他线程修改了value, 那么就把value重新赋值给oldValue. 

当然, CAS也有缺点, CAS最大的缺陷就是ABA问题, 即其他线程插入进来之后, 先把A改成B, 然后又把B改成A, 这样的话CAS就无法察觉到这样的变化. 为了解决这个问题, 又引入了"版本号", 简单理解就是A只能向B方向变, 不能向另一个方向变.
 

二. Callable接口

我们知道, run方法的修饰符是void, 即没有返回值. 所以为了解决这个问题, 我们可以使用Callable接口中的call方法. call()方法就相当于带有返回值的run()方法. Callable接口还提供了get()方法, get()相当于带有返回值的join()方法.

三. Semaphore 

Semaphore (信号量) --> 用来衡量当前可用资源的个数, 相当于一个计数器.

四. CountDownLath

一般, 当一个任务的体量很大的时候, 我们会把它拆成多个小的任务去执行. 那么如何衡量当前所与任务都执行完毕了? --> CountDownLath就能衡量出当前任务是否整体执行结束. 


原文地址:https://blog.csdn.net/2301_80313139/article/details/143724567

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!