• Java并发原子类有哪些?如何使用?


    • JDK Atomic开头的类,是通过 CAS 原理解决并发情况下原子性问题
    • CAS 包含 3 个参数,CAS(V, E, N)。V 表示需要更新的变量,E 表示变量当前期望值,N 表示更新为的值。只有当变量 V 的值等于 E 时,变量 V 的值才会被更新为 N。如果变量 V 的值不等于 E ,说明变量 V 的值已经被更新过,当前线程什么也不做,返回更新失败
    • 当多个线程同时使用 CAS 更新一个变量时,只有一个线程可以更新成功,其他都失败。失败的线程不会被挂起,可以继续重试 CAS,也可以放弃操作
    • CAS 操作的原子性是通过 CPU 单条指令完成而保障的。JDK 中是通过 Unsafe 类中的 API 完成的
    • 在并发量很高的情况,会有大量 CAS 更新失败和重试,所以需要慎用
    • java.util.concurrent.atomic 包中的原子分为:原子性基本数据类型、原子性对象引用类型、原子性数组、原子性对象属性更新器和原子性累加器
    原子性基本数据类型:AtomicBoolean、AtomicInteger、AtomicLong
    原子性对象引用类型:AtomicReference、AtomicStampedReference、AtomicMarkableReference
    原子性数组:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray
    原子性对象属性更新:AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdater
    原子性累加器:DoubleAccumulator、DoubleAdder、LongAccumulator、LongAdder

    未使用原子类,测试代码

    package constxiong.interview;
     
    /**
     * JDK 原子类测试
     * @author ConstXiong
     */
    public class TestAtomic {
     
    	private int count = 0;
    	
    	public int getAndIncrement() {
    		return count++;
    	}
    	
    //	private AtomicInteger count = new AtomicInteger(0);
    //	
    //	public int getAndIncrement() {
    //		return count.getAndIncrement();
    //	}
    	
    	public static void main(String[] args) {
    		final TestAtomic test = new TestAtomic();
    		for (int i = 0; i <3; i++) {
    			new Thread(){
    				@Override
    				public void run() {
    					for (int j = 0; j <10; j++) {
    						try {
    							Thread.sleep(100);
    						} catch (InterruptedException e) {
    							e.printStackTrace();
    						}
    						System.out.println(Thread.currentThread().getName() + " 获取递增值:" + test.getAndIncrement());
    					}
    				}
    			}.start();
    		}
    	}
    	
    	
    }

    打印结果中,包含重复值

    Thread-0 获取递增值:1
    Thread-2 获取递增值:2
    Thread-1 获取递增值:0
    Thread-0 获取递增值:3
    Thread-2 获取递增值:3
    Thread-1 获取递增值:3
    Thread-2 获取递增值:4
    Thread-0 获取递增值:5
    Thread-1 获取递增值:5
    Thread-1 获取递增值:6
    Thread-2 获取递增值:8
    Thread-0 获取递增值:7
    Thread-1 获取递增值:9
    Thread-0 获取递增值:10
    Thread-2 获取递增值:10
    Thread-0 获取递增值:11
    Thread-2 获取递增值:13
    Thread-1 获取递增值:12
    Thread-1 获取递增值:14
    Thread-0 获取递增值:14
    Thread-2 获取递增值:14
    Thread-1 获取递增值:15
    Thread-2 获取递增值:15
    Thread-0 获取递增值:16
    Thread-1 获取递增值:17
    Thread-0 获取递增值:19
    Thread-2 获取递增值:18
    Thread-0 获取递增值:20
    Thread-1 获取递增值:21
    Thread-2 获取递增值:22

    测试代码修改为原子类

    package constxiong.interview;
     
    import java.util.concurrent.atomic.AtomicInteger;
     
    /**
     * JDK 原子类测试
     * @author ConstXiong
     * @date 2019-06-11 11:22:01
     */
    public class TestAtomic {
     
    //	private int count = 0;
    //	
    //	public int getAndIncrement() {
    //		return count++;
    //	}
    	
    	private AtomicInteger count = new AtomicInteger(0);
    	
    	public int getAndIncrement() {
    		return count.getAndIncrement();
    	}
    	
    	public static void main(String[] args) {
    		final TestAtomic test = new TestAtomic();
    		for (int i = 0; i <3; i++) {
    			new Thread(){
    				@Override
    				public void run() {
    					for (int j = 0; j <10; j++) {
    						try {
    							Thread.sleep(100);
    						} catch (InterruptedException e) {
    							e.printStackTrace();
    						}
    						System.out.println(Thread.currentThread().getName() + " 获取递增值:" + test.getAndIncrement());
    					}
    				}
    			}.start();
    		}
    	}
    	
    	
    }
    

    打印结果中,不包含重复值

    Thread-0 获取递增值:1
    Thread-2 获取递增值:2
    Thread-1 获取递增值:0
    Thread-0 获取递增值:3
    Thread-1 获取递增值:4
    Thread-2 获取递增值:5
    Thread-0 获取递增值:6
    Thread-1 获取递增值:7
    Thread-2 获取递增值:8
    Thread-0 获取递增值:9
    Thread-2 获取递增值:10
    Thread-1 获取递增值:11
    Thread-0 获取递增值:12
    Thread-1 获取递增值:13
    Thread-2 获取递增值:14
    Thread-0 获取递增值:15
    Thread-1 获取递增值:16
    Thread-2 获取递增值:17
    Thread-0 获取递增值:18
    Thread-1 获取递增值:19
    Thread-2 获取递增值:20
    Thread-0 获取递增值:21
    Thread-2 获取递增值:23
    Thread-1 获取递增值:22
    Thread-0 获取递增值:24
    Thread-1 获取递增值:25
    Thread-2 获取递增值:26
    Thread-0 获取递增值:27
    Thread-2 获取递增值:28
    Thread-1 获取递增值:29


    原文链接
     


     

  • 相关阅读:
    强类型、弱类型、静态、动态语言定义(转载)
    What is a non-trivial constructor in C++?(转载)
    面试准备之面试题(C++) (一)
    python实现tail(考虑到几种特殊情况)
    rsyslog应用案例
    FUCK, 排查python写入mysql数据库过慢的过程(心都碎了)
    svn相关操作
    springCloud学习中遇到的问题
    idea启动项目没错,可是debug却一直启动不起来
    前端控制台返回406错误解决方法
  • 原文地址:https://www.cnblogs.com/ConstXiong/p/12118076.html
Copyright © 2020-2023  润新知