无锁的线程安全整数 AtomicInteger
为了能够受益于CAS等CPU指令,JDK并发包中有一个Atomic包,里面实现了一些直接使用CAS操作的线程安全的类型
下面是AtomicInteger的一些常用方法,对应其他原子类,操作是类似的.

内部实现上来说,AtomicInteger中保存一个核心字段
1
| private volatile int value;
|
1
| private static final long valueOffset;
|
一个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerDemo { static AtomicInteger i =new AtomicInteger(10);
public static class AddThread implements Runnable { @Override public void run() { for(int k=0;k<1000;k++) { i.incrementAndGet(); System.out.println(i); System.out.println(i +" "+Thread.currentThread().getId()); } } }
public static void main(String[] args) throws Exception { Thread[] ts =new Thread[10]; for(int k=0;k<10;k++) { ts[k]=new Thread(new AddThread()); }
for(int k=0;k<10;k++) { ts[k].start(); }
System.out.println(i); } }
|
AtomicReference 无锁的对象引用
AtomicReference 和AtomicInteger 非常类似,不同之处在于AtomicInteger是对整数的封装,而AtomicReference对应普通的对象引用.它可以保证用户在修改对象引用时的线程安全性.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class AtomicReferenceDemo { public static void main(String[] args){ Person p1 = new Person(101); Person p2 = new Person(102); AtomicReference<Person> ar = new AtomicReference<>(p1); ar.compareAndSet(p1, p2); Person p3 = ar.get(); System.out.println("p3 is "+p3); System.out.println("p3.equals(p1)="+p3.equals(p1)); System.out.println("p3.equals(p2)="+p3.equals(p2)); } } class Person { volatile long id; public Person(long id) { this.id = id; } public String toString() { return "id:"+id; } }
|
AtomicIntegerArray 无锁的数组
除基本数据类型外,JDK还准备了数组等复合结构,
AtomicIntegerArray 本质是对int[] 类型的封装,使用UNSAFE类通过CAS的方式控制int[] 在多线程下的安全性.有如下常用API
1 2 3 4 5 6 7
| public final int get(int i); public final int length(); public final int getAndSet(int i,int newValue) public final boolean compareAndSet(int i,int expect,int update) public final int getAndIncrement(int i) public final int getAndDecrement(int i) public final int getAndAdd(int i,int delta)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class AtomicIntegerArrayDemo { static AtomicIntegerArray array =new AtomicIntegerArray(10); public static class AddThread implements Runnable { public void run() { for(int k=0;k<1000;k++) { array.getAndIncrement(k%array.length()); } } } public static void main(String args[]) throws Exception { Thread ts[] =new Thread[10]; for(int k=0;k<10;k++) { ts[k]=new Thread(new AddThread()); } for(int k=0;k<10;k++) { ts[k].start(); }
Thread.sleep(5000); System.out.println(array); } }
|
AtomicIntegerFieldUpdater 让类中某变量也可以原子操作