• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
风拂晚柳
博客园    首页    新随笔    联系   管理    订阅  订阅

Java多线程-----原子变量和CAS算法

   原子变量

     原子变量保证了该变量的所有操作都是原子的,不会因为多线程的同时访问而导致脏数据的读取问题

     Java给我们提供了以下几种原子类型:

  • AtomicInteger和AtomicIntegerArray:基于Integer类型
  • AtomicBoolean:基于Boolean类型
  • AtomicLong和AtomicLongArray:基于Long类型
  • AtomicReference和AtomicReferenceArray:基于引用类型

1.非原子操作

package com.thread.atomic;

/**
 * 非原子操作
 * 
 * @author yyx 2019年1月14日
 */
public class NoAtomic {
    public static void main(String[] args) {
        NoAtomicDemo noAtomicDemo = new NoAtomicDemo();
        for (int i = 0; i < 10; i++) {
            new Thread(noAtomicDemo).start();
        }
    }
}

class NoAtomicDemo implements Runnable {
    private volatile int serialNumber = 0;

    @Override
    public void run() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
        }

        System.out.print(getSerialNumber()+" ");
    }

    public int getSerialNumber() {
        return serialNumber++;
    }
}
运行结果的一种:0 0 5 7 4 1 2 3 7 6 

2.原子操作

package com.thread.atomic;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 原子操作
 * 
 * @author yyx 2019年1月14日
 */
public class HaveAtomic {
    public static void main(String[] args) {
        HaveAtomicDemo hAtomicDemo = new HaveAtomicDemo();
        for (int i = 0; i < 10; i++) {
            new Thread(hAtomicDemo).start();
        }
    }
}

class HaveAtomicDemo implements Runnable {
    private AtomicInteger aInteger = new AtomicInteger();

    @Override
    public void run() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
        }

        System.out.print(getaInteger() + " ");
    }

    public int getaInteger() {
        return aInteger.getAndIncrement();
    }
}
运行结果的一种:0 2 7 8 9 5 6 3 4 1 

   CAS算法思想

     三个参数,一个当前内存值V、旧的预期值A、即将更新的值B,当且仅当预期值A和内存值V相同时,将内存值修改为B并返回true,否则什么都不做,并返回false

package com.thread.atomic;

/**
 * 模拟 CAS 算法
 * 
 * @author yyx 2019年1月14日
 */
public class CASAlgorithm {
    public static void main(String[] args) {
        final CompareAndSwap cas = new CompareAndSwap();

        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    int expectedValue = cas.get();
                    boolean b = cas.compareAndSet(expectedValue, (int) (Math.random() * 101));
                    System.out.println(b);
                }
            }).start();
        }
    }
}

class CompareAndSwap {
    private int value;

    // 获取内存值
    public synchronized int get() {
        return value;
    }

    // 比较
    public synchronized int compareAndSwap(int expectedValue, int newValue) {
        int oldValue = value;

        if (oldValue == expectedValue) {
            this.value = newValue;
        }

        return oldValue;
    }

    // 设置
    public synchronized boolean compareAndSet(int expectedValue, int newValue) {
        return expectedValue == compareAndSwap(expectedValue, newValue);
    }
}

 

posted @ 2019-01-14 21:19  风拂晚柳  阅读(156)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3