zoukankan      html  css  js  c++  java
  • Java并发编程原理与实战十三: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
            } Object pre

    参考资料:

    《java并发编程与实战》龙果学院

  • 相关阅读:
    Oct 21st-
    ContextLoaderListener 解析
    HTTPS 证书制作及使用
    Spring MVC 源码分析
    思考
    《深入理解java虚拟机》 第七章虚拟机类加载机制
    《深入理解java虚拟机》第六章 类文件结构
    《深入理解java虚拟机》第三章 垃圾收集器与内存分配策略
    《深入理解java虚拟机》第二章 Java内存区域与内存溢出异常
    SSM-1第一章 认识SSM框架和Redis
  • 原文地址:https://www.cnblogs.com/pony1223/p/9404990.html
Copyright © 2011-2022 走看看