首页 > 编程语言 > 详细

多线程-CAS操作

时间:2020-07-21 12:29:53      阅读:59      评论:0      收藏:0      [点我收藏+]

CAS操作号称无锁优化,也叫作自旋;对于一些常见的操作需要加锁,然后jdk就提供了一些以Atomic开头的类,这些类内部自动带了锁,当然这里的锁并非是用synchronized来实现的,而是通过CAS操作来实现的;

一、下面是 AtomicInteger 的使用:

package com.designmodal.design.juc01;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author D-L
 * @Classname T03_AtomicInteger
 * @Version 1.0
 * @Description  使用 AtomicInteger 类解决常见的 多线程count++
 *               其内部使用了CAS操作来保证原子性  但是不能保证多个方法连续调用都是原子性
 * @Date 2020/7/21 0:35
 */
public class T03_AtomicInteger {
    //使用AtomicInteger类
    AtomicInteger count = new AtomicInteger(0);

    public void m(){
        for (int i = 0; i < 10000; i++) {
            //等同于 在 count++ 上加锁
            count.incrementAndGet();
        }
    }

    public static void main(String[] args) {
        T03_AtomicInteger t = new T03_AtomicInteger();
        List<Thread> threads = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            threads.add(new Thread(t::m , "Thread" + i));
        }
        threads.forEach((o) -> o.start());
        threads.forEach(o ->{
            try {
                o.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        System.out.println(t.count);
    }
}

二、当然达到使用的级别很简单,看一下API就好了,通过上面的小程序,下面主要来聊一聊原理:

1、首先小程序中定义了一个 AtomicInteger 类型的变量count;

 AtomicInteger count = new AtomicInteger(0);
 public void add(){
count.incrementAndGet();
}

2、调用了AtomicInteger类中incrementAndGet();

/**
     * Atomically increments by one the current value.
     *
     * @return the updated value
     */
    public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }

3、调用unsafe类中的 getAndAddInt(Object var1, long var2, int var4)方法;

public native int getIntVolatile(Object var1, long var2);
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);


 public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }

 这里通过以上三步的操作,最终会进入Unsafe类这里调用的 compareAndSwapInt 意思就是比较然后交换,通过一个while循环,在这里转呀转,直到修改成功;

CAS(compareAndSwap)(比较并交换):原来想改变的值为0 ,现在想修改成1 ,这里想做到线程安全就必须要加synchronized,现在想用另外一种方式来替换加锁的方法,就是所谓的CAS操作;你可以把它想象成拥有三个参数的方法cas(V ,  Expected  ,  NewValue); 

多线程-CAS操作

原文:https://www.cnblogs.com/dongl961230/p/13352744.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!