zoukankan      html  css  js  c++  java
  • 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);
        }
    }
  • 相关阅读:
    04: Dom
    03: JavaScript基础
    02: css常用属性
    01: html常用标签
    03: Memcached
    01: Redis缓存系统
    01: RabbitMQ
    04: 事件驱动、五种I/O操作、I/O多路复用select和epoll
    03: 进程、线程、协程
    [Android] 任意时刻从子线程切换到主线程的实现
  • 原文地址:https://www.cnblogs.com/fengfuwanliu/p/10268911.html
Copyright © 2011-2022 走看看