线程与并发 - CAS与Atomic*

多线程与高并发
  • CAS compare and swap 比较并交换
  • CAS 又称无锁优化 | 自旋锁 | 轻量级锁 | 乐观锁
  • CAS 算法 – 个人白话理解:
    cas相当于 cas(int value,int except,int newValue)方法 value-我每次获取到的值,except - 我期望我每次获取到的值,newValue - 我想把我获取到的值修改成的新值;我每一次自旋,都会比较value 与 except是否相等,如果不相等,说明value已经被其它的线程修改了,我就cas再重新试一下,如果相等了我就把变量值改成newValue。
CAS的ABA问题

ABA就是说两个线程t1,t2都读取到了i=1,但是t1 +1之后 又进行了-1 那么我t2是不知道你中间这个值是修改过,不会影响我的cas下面的操作。
解决:加版本号 检查的时候连同版本号一同检查
如果是变量是基础类型:不影响结果值,无所谓。
如果是变量是引用类型:就相当于我之前有个对象,分手之后又复合,但是中间对象经历了别的人。

Atomic*
  • Atomic* 类是java原生自带的内部实现cas保证原子性的类
  • Atomic 底层用的是Unsafe这个类 直接操作内存,类,实例变量,直接生成类实例。1.8版本之前是 CompareAndSet 之后是 weekCompareAndSetObject 方法
  • 应用:cas解决线程同步问题
public class Thread_015 {
    AtomicInteger count = new AtomicInteger(0);
    void add(){
        for (int i = 0; i < 10000; i++) {
            count.incrementAndGet();//内部cas实现保证原子性
        }
    }
    public static void main(String[] args) {
        Thread_015 t = new Thread_015();
        List<Thread> list = new ArrayList<Thread>();
        for (int i = 0; i < 10; i++) {
            list.add(new Thread(t::add));
        }
        list.forEach(t1->t1.start());
        list.forEach(t2-> {
            try {
                t2.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println("count:"+t.count);
    }
}
sychronized | Atomic* |LongAdder 效率比较
  • 对比下来LongAdder效率是最高的 它内部应用了分段锁
  • Atomic* 与sychronized 具体得看实际应用场景
public class Thread_016 {
    static int count1=0;
    static AtomicInteger count2 = new AtomicInteger(0);
    static LongAdder count3 = new LongAdder();

    public static void main(String[] args) throws Exception{
        List<Thread> threads1 = new ArrayList<>();
        Object lock = new Object();

        for (int i = 0; i < 1000; i++) {
            threads1.add(new Thread(()->{
                for (int j = 0; j < 100000; j++) {
                    synchronized (lock){
                        count1++;
                    }
                }
            }));
        }
        long start1 = System.currentTimeMillis();
        threads1.forEach(thread1 -> thread1.start());
        threads1.forEach(thread1 -> {
            try {
                thread1.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println("count:"+count1+" synchronized time:"+ (System.currentTimeMillis() - start1));

        List<Thread> threads2 = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            threads2.add(new Thread(()->{
                for (int j = 0; j < 100000; j++) {
                    count2.incrementAndGet();
                }
            }));
        }
        long start2 = System.currentTimeMillis();
        threads2.forEach(thread2 -> thread2.start());
        threads2.forEach(thread2 -> {
            try {
                thread2.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println("count:"+count2+" Atomic time:"+ (System.currentTimeMillis() - start2));

        List<Thread> threads3 = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            threads3.add(new Thread(()->{
                for (int j = 0; j < 100000; j++) {
                    count3.increment();
                }
            }));
        }
        long start3 = System.currentTimeMillis();
        threads3.forEach(thread3 -> thread3.start());
        threads3.forEach(thread3 -> {
            try {
                thread3.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println("count:"+count3+" LongAdder time:"+ (System.currentTimeMillis() - start3));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值