原子变量
原子变量保证了该变量的所有操作都是原子的,不会因为多线程的同时访问而导致脏数据的读取问题
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); } }