本文共 3321 字,大约阅读时间需要 11 分钟。
一、AtomicInteger等
Atomic是一系列原子类:
* AtomicInteger,AtomicLong,AtomicReference,AtomicIntegerArray...。 * 内部实现原理是:循环CAS。public class AtomicBaseDemo { public static void main(String[] args) throws InterruptedException { //一、Api基本使用 AtomicInteger atomicInt = new AtomicInteger(1); int incrementAndGet = atomicInt.incrementAndGet(); boolean compareAndSet = atomicInt.compareAndSet(3, 11); // 此时预期应该是2 System.out.println(compareAndSet); // false System.out.println(atomicInt.compareAndSet(2, 10)); // true System.out.println(atomicInt.get()); // 10 System.out.println(atomicInt.getAndAdd(10)); // 10,返回10,实际值是20 System.out.println(atomicInt.getAndSet(5)); // 20, 返回5,实际值是5. //二、案例 atomicInt.set(0); final int threadSize = 1000; Thread[] ts = new Thread[threadSize]; for (int i = 0; i < threadSize; i++) { ts[i] = new Thread() { public void run() { atomicInt.incrementAndGet(); } }; } for (Thread t : ts) { t.start(); } for (Thread t : ts) { t.join(); } System.out.println(atomicInt.get()); // 1000 }}
二、AtomicReference
概述:原子数组主要由AtomicIntegerArray/AtomicLongArray这些包装类
* 主要Api方法:getAndIncrement(index),即比AtomicInteger多了一个index参数public class ArrayAtomicDemo { private static int THREADCOUNT = 1000; private static CountDownLatch countDown = new CountDownLatch(THREADCOUNT); private static int[] values = new int[10]; private static AtomicIntegerArray atomicValues = new AtomicIntegerArray(values); public static void main(String[] args) throws InterruptedException { // 1、1000个线程,每个线程循环100次,每次每个元素+1 for (int i = 0; i < THREADCOUNT; i++) { new Thread(()->{ for (int j = 0; j < 100; j++) { for (int k = 0; k < values.length; k++) { values[k]++; } } countDown.countDown(); }).start(); } countDown.await(); for (int i = 0; i < 10; i++) { System.out.print(values[i]+" "); } //99873 99878 99872 99868 99863 99856 99868 99862 99851 99853 System.out.println(); // 2、1000个线程,每个线程循环100次,每次每个元素+1,使用AtomicIntegerArray。 countDown = new CountDownLatch(THREADCOUNT); for (int i = 0; i < THREADCOUNT; i++) { new Thread(()->{ for (int j = 0; j < 100; j++) { for (int k = 0; k < values.length; k++) { atomicValues.getAndIncrement(k); } } countDown.countDown(); }).start(); } countDown.await(); for (int i = 0; i < 10; i++) { System.out.print(atomicValues.get(i)+" "); } //100000 100000 100000 100000 100000 100000 100000 100000 100000 100000 } }
三、AtomicReference
* AtomicReference引用原子包装类
* 概述:AtomicInteger是对int,AtomicIntegerArray是对数组的一些CAS操作api的集合, * 那么AtomicReference就是包装引用类型,比如compareAndSet(expect,update)。它有一个 * 泛型,可以指定被包装引用的类型。下面是模拟并发栈。public class AtomicReferenceDemo{ AtomicReference > first = new AtomicReference >(); public void push(E e){ Node newHead = new Node (e); Node oldHead; for (;;) { oldHead = first.get(); /**内部是原子变量*/ newHead.next = oldHead; if(first.compareAndSet(oldHead, newHead)){ /**利用本地方法的cas操作*/ break; } } } public E pop(){ Node oldHead; Node newHead; do { oldHead = first.get(); if (oldHead == null) return null; newHead = oldHead.next; } while (!first.compareAndSet(oldHead, newHead)); return oldHead.item; } private static class Node { final E item; Node next; /**因为都是一端进行操作,所以next不用Atomic包装!*/ public Node(E item) { this.item = item; } }}
转载地址:http://zeuni.baihongyu.com/