• JDK提供的原子类原理与使用


    原子更新基本类型

    原子更新数组

    原子更新抽象类型

    原子更新字段

    原子更新基本类型:

    package com.roocon.thread.t8;

    import java.util.concurrent.atomic.AtomicInteger;
    import java.util.concurrent.atomic.AtomicIntegerArray;

    public class Sequence {
    private AtomicInteger value = new AtomicInteger(0);
    private int [] s = {2,1,4,6};
    AtomicIntegerArray a = new AtomicIntegerArray(s);

    public int getNext(){
    a.getAndIncrement(2);//给下标为2的元素加1
    a.getAndAdd(2, 10);//获取下标为2的元素,并且加10
    for (int i=0; i < a.length(); i++){
    System.out.println(a.get(i));
    }
    return value.getAndIncrement();
    }

    public static void main(String[] args) {
    Sequence sequence = new Sequence();
    new Thread(new Runnable() {
    @Override
    public void run() {
    while (true){
    System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
    try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }).start();
    new Thread(new Runnable() {
    @Override
    public void run() {
    while (true){
    System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
    try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }).start();
    new Thread(new Runnable() {
    @Override
    public void run() {
    while (true){
    System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
    try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }).start();
    }
    }

    运行结果:

    Thread-0 0
    Thread-1 1
    Thread-2 2
    Thread-0 3
    Thread-1 4
    Thread-2 5
    ...
    package com.roocon.thread.t8;
    
    import java.util.concurrent.atomic.AtomicInteger;
    import java.util.concurrent.atomic.AtomicIntegerArray;
    import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
    import java.util.concurrent.atomic.AtomicReference;
    
    public class Sequence {
        private AtomicInteger value = new AtomicInteger(0);
        AtomicReference<User> user = new AtomicReference<>(); //对user的set和get执行原子操作
        AtomicIntegerFieldUpdater<User> old =  AtomicIntegerFieldUpdater.newUpdater(User.class, "old");
    
        public int getNext(){
            User user = new User();
            System.out.println(old.getAndIncrement(user));
            System.out.println(old.getAndIncrement(user));
            System.out.println(old.getAndIncrement(user));
            return value.getAndIncrement();
        }
    
        public static void main(String[] args) {
            Sequence sequence = new Sequence();
            new Thread(new Runnable() {
                @Override
                public void run() {
                       System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
                       try {
                           Thread.sleep(100);
                       } catch (InterruptedException e) {
                           e.printStackTrace();
                       }
                   }
            }).start();
        }
    }

    运行结果:

    0
    1
    2
    Thread-0 0

    对CAS的源码理解:--初步理解

    在AtomicInteger中有这样一段源码:

    public final int getAndUpdate(IntUnaryOperator updateFunction) {
            int prev, next;
            do {
                prev = get();
                next = updateFunction.applyAsInt(prev);
            } while (!compareAndSet(prev, next));
            return prev;
        }

    public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
     

    其中,compareAndSwap就是CAS的缩写。如果prev和next不相等,则返回true。否则,返回false。最终是通过unsafe来实现的。

    以上代码表示,如果compareAndSet返回true,则while条件为false,退出循环,返回prev值。如果compareAndSet返回false,则while为true,继续执行循环体,重新获取prev的值,重新获取更新值,直到返回的compareAndSet值为true。

    演示源码大致步骤如下:

     Object prev = get(); //1
            next = prev + 1;
            boolean flag = cas(prev, next);
            if (flag) {
                return prev;
            }else {
                go to 1
            }
  • 相关阅读:
    GDC快讯,腾讯CMatrix布局云游戏B端领域
    如何测试小程序? 腾讯智慧零售保障优衣库小程序体验优化
    一分钟读懂兼容报告:测试过程视频复现,问题定位很轻松
    一到秒杀就瘫痪?压测大师保你后台稳健
    how2j-springcloud-摘抄
    问题1
    springcloud---how2java--记录零碎的信息
    how2java-springcloud-demo
    oracle 查两个日期之间数据有多少条
    非官网渠道下单导致的错误
  • 原文地址:https://www.cnblogs.com/sunnyDream/p/8137588.html
Copyright © 2020-2023  润新知