Java中高级核心知识全面解析——Atomic(什么是Atomic原子类、基本类型原子类、数组类型原子类、引用类型原子类?)

本文深入解析Java中的Atomic原子类,包括基本类型原子类如AtomicInteger,数组类型原子类如AtomicIntegerArray,引用类型原子类如AtomicReference,以及对象属性修改类型原子类如AtomicIntegerFieldUpdater。通过实例展示了如何使用这些类进行线程安全的原子操作,同时探讨了Atomic类在并发编程中的优势和线程安全原理。
摘要由CSDN通过智能技术生成

一、Atomic 原子类介绍

Atomic翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里 Atomic是指一个操作是不可中断的即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。

所以,所谓原子类说简单点就是具有原子/原子操作特征的类。

并发包java.util.concurrent的原子类都存放在java.util.concurrent.atomic下,如下图所示。
image
根据操作的数据类型,可以将JUC包中的原子类分为4类

基本类型

使用原子的方式更新基本类型

  • AtomicInteger整型原子类
  • AtomicLong长整型原子类
  • AtomicBoolean布尔型原子类

数组类型

使用原子的方式更新数组里的某个元素

  • AtomicIntegerArray整型数组原子类
  • AtomicLongArray长整型数组原子类
  • AtomicReferenceArray引用类型数组原子类

引用类型

  • AtomicReference引用类型原子类
  • AtomicMarkableReference原子更新带有标记的引用类型。该类将boolean标记与引用关联起来,也可以解决使用CAS进行原子更新时可能出现的ABA问题。
  • AtomicStampedReference原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于解决原子的更新数据和数据的版本号,可以解决使用CAS进行原子更新时可能出现的ABA问题。

对象的属性修改类型

  • AtomicIntegerFieldUpdater:原子更新整型字段的更新器
  • AtomicLongFieldUpdater原子更新长整型字段的更新器
  • AtomicReferenceFieldUpdater原子更新引用类型里的字段

修正: AtomicMarkableReference不能解决ABA问题

/**
AtomicMarkableReference是将一个boolean值作是否有更改的标记,本质就是它的版本号只有两个, true和false, 
修改的时候在这两个版本号之间来回切换,这样做并不能解决ABA的问题,只是会降低ABA问题发生的几率而已
@author : mazh 
@Date : 2020/12/9 14:41 
*/

public class SolveABAByAtomicMarkableReference {
   
		private static AtomicMarkableReference atomicMarkableReference = new 
AtomicMarkableReference(100, false);
		public static void main(String[] args) {
    
		
			Thread refT1 = new Thread(() -> {
    
				try {
   TimeUnit.SECONDS.sleep(1); 
				} catch (InterruptedException e) {
   
					 e.printStackTrace(); 
				}
				atomicMarkableReference.compareAndSet(100, 101, 
				atomicMarkableReference.isMarked(), !atomicMarkableReference.isMarked());
				atomicMarkableReference.compareAndSet(101, 100, 
				atomicMarkableReference.isMarked(), !atomicMarkableReference.isMarked());
			});
			Thread refT2 = new Thread(() -> {
    
				boolean marked = atomicMarkableReference.isMarked(); 
				try {
   
					TimeUnit.SECONDS.sleep(2); 
				} catch (InterruptedException e) {
    
					e.printStackTrace(); 
				}
				boolean c3 = atomicMarkableReference.compareAndSet(100, 101, 
marked, !marked);
				System.out.println(c3); // 返回true,实际应该返回false 
				}); 

				refT1.start(); 
				refT2.start(); 
			} 
		}

CAS ABA 问题

  • 描述: 第一个线程取到了变量 x 的值 A,然后巴拉巴拉干别的事,总之就是只拿到了变量 x 的值A。这段时间内第二个线程也取到了变量 x 的值 A,然后把变量 x 的值改为 B,然后巴拉巴拉干别的事,最后又把变量 x 的值变为 A (相当于还原了)。在这之后第一个线程终于进行了变量 x 的操作,但是此时变量 x 的值还是 A,所以compareAndSet操作是成功。
  • 例子描述(可能不太合适,但好理解): 年初,现金为零,然后通过正常劳动赚了三百万,之后正常消费了(比如买房子)三百万。年末,虽然现金零收入(可能变成其他形式了),但是赚了钱是事实,还是得交税的!
  • 代码例子(以AtomicInteger为例)
import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerDefectDemo {
    
		public static void main(String[] args) {
    
			defectOfABA(); 
		}
		
		static void defectOfABA() {
    
			final AtomicInteger atomicInteger = new AtomicInteger(1);
			
			Thread coreThread = new Thread( 
					() -> {
    
						final int currentValue = atomicInteger.get(); 
						System.out.println(Thread.currentThread().getName() + " ---- 
-- currentValue=" + currentValue);

						// 这段目的:模拟处理其他业务花费的时间
						try {
   
							Thread.sleep(300); 
						} catch (InterruptedException e) {
   
						 	e.printStackTrace(); 
						 }
						 
						 boolean casResult = atomicInteger.compareAndSet(1, 2);
						 System.out.println(Thread.currentThread().getName() 
						 		+ " ------ currentValue=" + currentValue 
						 		+ ", finalValue=" + atomicInteger.get() 
						 		+ ", compareAndSet Result=" + casResult); 
				} 
		);
		coreThread.start();

		// 这段目的:为了让 coreThread 线程先跑起来
		try {
   
			Thread.sleep(100); 
		} catch (InterruptedException e) {
    
			e.printStackTrace(); 
		}
		
		Thread amateurThread = new Thread( 
				() -> {
    
					int currentValue 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值