java多线程之原子类

  • 当程序更新时,如果多个线程同时操作一个变量进行如i++的操作,会造成线程不安全的更新操作,通常采用synchronized来解决这个问题
    • juc这个包的出现提供了新的解决思路,提供的原子操作类 简单,高效,线程安全
      • 基本类型
        • AtomicInteger
        • AtomicBoolean
        • AtomicLong
        • 提供的用法都一致,以AtomicInteger为例
          • int addAndGet(int delta) 以原子方式将输入的参数与实例中的值相加并将结果返回
          •  AtomicInteger ai = new AtomicInteger(2); 
            ai.addAndGet(10);
            System.out.println(ai.get());//输出12
          • boolean compareAndSet(expect,update) 如果输入的值等于预期值则以原子方式将该值设置为输入的值 CAS
            • Unsafe.
              • compareAndSwapObject
              • compareAndSwapLong
              • compareAndSwapInt
          •  AtomicInteger ai = new AtomicInteger(2); 
            ai.addAndGet(10);// ai=12
            ai.compareAndSet(12,13);
            System.out.println(ai.get());//输出13
          • int getAndIncreament() 以原子方式将当前值+1,该方法返回增加前的值
          • void lazySet(int newValue) 最终会设置成newValue 一段时间内读到的是旧值 set()立即更新
            • 就是在不需要让共享变量的修改立刻让其他线程可见的时候,以设置普通变量的方式来修改共享状态,可以减少不必要的内存屏障,从而提高程序执行的效率
            • public final void lazySet(long newValue) { 
              unsafe.putOrderedLong(this, valueOffset, newValue);
              }
          • int getAndSet(int newValue) 以原子方式设置newValue 返回旧值
      • 原子更新数组
        • AtomicIntegerArray
          • int addAndGet(int i,int delta) 输入值delta与索引值i对应的值相加
          • boolean compareAndSet(int i,expect,update)
        • AtomicLongArray
        • AtomicReferenceArray
        • 以数组传入 不会更新数组的原有值
      • 原子更新引用类型
        • AtomicReference 引用类型
        • AtomicReferenceFiledUpdater 引用类型的字段
        • AtomicMarkableReference 带有标记位的引用类型
        • User user = new User("aaa",1); 
          ref.set(user);
          User userForUpdate = new User("bbb",2);
          ref.compareAndSet(user,userForUpdate);
          System.out.println(user.getName());//aaa
          System.out.println(user.getOld());//1
          System.out.println("-----------------------");
          System.out.println(ref.get().getName());//bbb
          System.out.println(ref.get().getOld());//2
      • 原子更新字段类
        • AtomicIntegerFieldUpdater
        • AtomicLongFieldUpdater
        • AtomicStampedReference //version 避免ABA问题
        • 调用newUpdater() 创建一个更新器
        • static AtomicIntegerFieldUpdater a = 
          AtomicIntegerFieldUpdater.newUpdater(User.class,"old");
          public static void main(String[] args) {
          User u = new User("kkk",10);
          System.out.println(a.getAndIncrement(u));
          System.out.println(a.get(u));
          }
          static class User{
          private String name;
          public volatile int old;
          public User(String name, int old) {
          this.name = name;
          this.old = old;
          }
          public String getName() {
          return name;
          }
          public void setName(String name) {
          this.name = name;
          }
          public int getOld() {
          return old;
          }
          public void setOld(int old) {
          this.old = old;
          }
          }

猜你喜欢

转载自blog.csdn.net/sinat_32197439/article/details/81809524