Atomic原子操作

Atomic包的作用

方便程序员在多线程环境下,无锁的进行原子操作

Atomic包核心

Atomic包里的类基本都是使用Unsafe实现的包装类,核心操作是CAS原子操作;

关于CAS

compare and swap,比较和替换技术,将预期值与当前变量的值比较(compare),如果相等则使用新值替换(swap)当前变量,否则不作操作;

现代CPU已广泛支持CAS指令,如果不支持,那么JVM将使用自旋锁,与互斥锁一样,两者都需先获取锁才能访问共享资源,但互斥锁会导致线程进入睡眠,而自旋锁会一直循环等待直到获取锁;

另外,有一点需要注意的是CAS操作中的ABA问题,即将预期值与当前变量的值比较的时候,即使相等也不能保证变量没有被修改过,因为变量可能由A变成B再变回A,解决该问题,可以给变量增加一个版本号,每次修改变量时版本号自增,比较的时候,同时比较变量的值和版本号即可;

Atomic包主要提供四种原子更新方式

原子方式更新基本类型;
原子方式更新数组;
原子方式更新引用;
原子方式更新字段;
原子方式更新基本类型
以下三个类是以原子方式更新基本类型

AtomicBoolean:原子更新布尔类型。
AtomicInteger:原子更新整型。
AtomicLong:原子更新长整型。
以AtomicInteger为例,

package concurrency;
import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerTest {

    static AtomicInteger ai = new AtomicInteger(1);

    public static void main(String[] args) {
        //相当于i++,返回的是旧值,看方法名就知道,先获取再自增
        System.out.println(ai.getAndIncrement());
        System.out.println(ai.get());
        //先自增,再获取
        System.out.println(ai.incrementAndGet());
        System.out.println(ai.get());
        //增加一个指定值,先add,再get
        System.out.println(ai.addAndGet(5));
        System.out.println(ai.get());
        //增加一个指定值,先get,再set
        System.out.println(ai.getAndSet(5));
        System.out.println(ai.get());
    }

}

注意:Atomic包提供了三种基本类型的原子更新,剩余的Java的基本类型还有char,float和double等,其更新方式可以参考AtomicBoolean的思路来现,AtomicBoolean是把boolean转成整型再调用compareAndSwapInt进行CAS来实现的,类似的short和byte也可以转成整形,float和double可以利用Float.floatToIntBits,Double.doubleToLongBits转成整形和长整形进行相应处理;

原子方式更新数组
以下三个类是以原子方式更新数组,

AtomicIntegerArray:原子更新整型数组里的元素。
AtomicLongArray:原子更新长整型数组里的元素。
AtomicReferenceArray:原子更新引用类型数组里的元素。
以AtomicIntegerArray为例,其方法与AtomicInteger很像,多了个数组下标索引;

package concurrency;

import java.util.concurrent.atomic.AtomicIntegerArray;

public class AtomicIntegerArrayTest {

    static int[] valueArr = new int[] { 1, 2 };

    //AtomicIntegerArray内部会拷贝一份数组
    static AtomicIntegerArray ai = new AtomicIntegerArray(valueArr);

    public static void main(String[] args) {
        ai.getAndSet(0, 3);
        //不会修改原始数组value
        System.out.println(ai.get(0));
        System.out.println(valueArr[0]);
    }

}

原子方式更新引用
以下三个类是以原子方式更新引用,与其它不同的是,更新引用可以更新多个变量,而不是一个变量;

AtomicReference:原子更新引用类型。
AtomicReferenceFieldUpdater:原子更新引用类型里的字段。
AtomicMarkableReference:原子更新带有标记位的引用类型。
以AtomicReference为例,

package concurrency;

import java.util.concurrent.atomic.AtomicReference;

public class AtomicReferenceTest {

    public static AtomicReference<User> atomicUserRef = new AtomicReference<User>();

    public static void main(String[] args) {
        User user = new User("conan", 15);
        atomicUserRef.set(user);
        User updateUser = new User("Shinichi", 17);
        atomicUserRef.compareAndSet(user, updateUser);
        System.out.println(atomicUserRef.get().getName());
        System.out.println(atomicUserRef.get().getOld());
    }

    static class User {
        private String name;
        private int old;

        public User(String name, int old) {
            this.name = name;
            this.old = old;
        }

        public String getName() {
            return name;
        }

        public int getOld() {
            return old;
        }
    }
}

原子方式更新字段
以下三个类是以原子方式更新字段,

AtomicIntegerFieldUpdater:原子更新整型字段的更新器。
AtomicLongFieldUpdater:原子更新长整型字段的更新器。
AtomicStampedReference:原子更新带有版本号的引用类型,用于解决使用CAS进行原子更新时,可能出现的ABA问题
以AtomicIntegerFieldUpdater为例,

package concurrency;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

public class AtomicIntegerFieldUpdaterTest {

    private static AtomicIntegerFieldUpdater<User> a = AtomicIntegerFieldUpdater
            .newUpdater(User.class, "old");

    public static void main(String[] args) {
        User conan = new User("conan", 10);
        System.out.println(a.getAndIncrement(conan));
        System.out.println(a.get(conan));
    }

    public static class User {
        private String name;
        //注意需要用volatile修饰
        public volatile int old;

        public User(String name, int old) {
            this.name = name;
            this.old = old;
        }

        public String getName() {
            return name;
        }

        public int getOld() {
            return old;
        }
    }
}

转载:https://www.cnblogs.com/chenpi/p/5375805.html

已有 17 条评论
  1. LesAstona

    Amoxicillin Allergic Reaction Treatment Propecia Prostate Cancer Prevention canadian cialis Achat Viagra Generique En France Cephalexin And Protocol

    LesAstona January 17th, 2020 at 07:37 pm回复
  2. KelSuefab

    Canada Pharmacies Online Prescriptions http://cheapcialisir.com - viagra vs cialis Free Generic Viagra Samples Cialis Anafranil Online

    KelSuefab January 29th, 2020 at 11:57 am回复
  3. MatInfoge

    Faux Viagra Au Quebec http://cialisjh.com - Buy Cialis Orlistat Order Online Canada cialis vs viagra Precio Levitra 20 Mg

    MatInfoge January 31st, 2020 at 02:13 am回复
  4. LesAstona

    Comprar Pastillas Levitra http://cialisjh.com - Buy Cialis Progesterone Website Mastercard Accepted Overseas Buy Cialis Comprar Kamagra Jelly

    LesAstona February 3rd, 2020 at 08:15 am回复
  5. StevWews

    Propecia Meteo Minoxidil http://apcialisle.com/# - Cialis Super Viagra To Buy Online Cialis Inhousepharmacybiz

    StevWews February 5th, 2020 at 10:20 am回复
  6. LesAstona

    Vipps Certified Pharmacy http://buycialisuss.com - cialis 5 mg best price usa Canadian Health Cialis Propecia Online With Prescription

    LesAstona February 21st, 2020 at 11:14 am回复
  7. EllEarnef

    Propecia Asepsia http://buycialisuss.com - Buy Cialis Buy Levitra Online 20mg Buy Cialis Viagra Original Rezept

    EllEarnef March 1st, 2020 at 06:54 am回复
  8. StevWews

    Comment Se Procurer Du Viagra Sans Ordonnance http://apcialisle.com/# - generic 5mg cialis best price Acquistare Viagra E Cialis Buy Cialis Kamagra A Buon Mercato

    StevWews March 4th, 2020 at 04:48 pm回复
  9. Stepsok

    Genericos De Cialis cialis 5 mg best price usa Propecia Online Order Cheap Cialis Trustedtablets Buy Viagra Usa

    Stepsok March 11th, 2020 at 12:20 pm回复
  10. Stepsok

    Buy Viagra In Ho Chi Minh 11 tadalafil cialis from india Lasix Ol Buy Cialis Propecia Oficial

    Stepsok March 15th, 2020 at 01:19 pm回复
  11. Janmit

    Propecia En Valencia Buy Cialis Overseas Pharmacy Buy Cialis Ordinare Viagra Online

    Janmit March 18th, 2020 at 04:38 pm回复
  12. Janmit

    Jelly Kamagra Disfuncion Erectil Cialis Acheter Du Xenical Moins Cher buy cialis cheap Suhagra 100 With Free Shipping

    Janmit March 20th, 2020 at 08:41 am回复
  13. Stepsok

    Viagra Through Mail best place to buy cialis online Zithromax Skin Reaction cialis generic release date Viagra Per Lei Pillola Rosa

    Stepsok March 26th, 2020 at 02:47 am回复
  14. Janmit

    Baisse Prix Kamagra Cialis Cialis Las Palmas cialis 10mg Cialis Generic Best Price

    Janmit April 23rd, 2020 at 04:36 pm回复
  15. Janmit

    Purchase Viagra generic cialis 5mg Zithromax Dosage For Dogs Cialis Dosis Kamagra Jelly

    Janmit April 24th, 2020 at 08:47 pm回复
  16. PigQuasug

    Primatene Mist Canada https://buyciallisonline.com/ - buying cialis online safely cialis viagra avis Buy Cialis Propecia Price Canada

    PigQuasug June 8th, 2020 at 04:19 pm回复
  17. typecycle

    cialis 5mg pricing cheapest cialis online Priligy Precio En Farmacias Buy Cialis Generic Amoxicillin

    typecycle June 12th, 2020 at 12:32 am回复
发表新评论