Atomic系列类封装了一系列的基础类型和对象操作,其主要目的就是为了实现原子性,可以在高并发时保障线程安全,主要核心类如下:
•AtomicInteger
•AtomicLong
•AtomicBoolean
•AtomicIntegerArray
•AtomicLongArray
•AtomicReference
public class UseAtomic {
/*常用数据类型无法保障在多线程的情况下的数据原子性
* private static int count = 0;
* public int add() {
count = count + 10;
return count;
}
*/
private static AtomicInteger count = new AtomicInteger(0);
/*
* 本意维持add()操作原子性,
* 但是一旦拆分操作就无法保障原子性
* 如果必须要这样操作,那么必须为此方法加上synchronized
* public synchronized int add()
*/
public int add() {
return count.addAndGet(10);//这样可以保障add()方法时原子性的
//下面这种方法不能保障add()的原子性,会出现某个线程读到的数据带有个位数,即add()方法未能执行完整的结果
//count.addAndGet(3);
//count.addAndGet(4);
//count.addAndGet(2);
//count.addAndGet(1);
return count.get();
}
public static void main(String[] args) {
UseAtomic ua = new UseAtomic();
List<Thread> list = new ArrayList();
/*
* 如果使用atomicIntger 最终结果一定是:1000
*/
for(int i=0;i<100;i++) {
list.add(new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
//一百个线程调用一百次add()方法
System.out.println("累计结果:"+ua.add());
}
}));
}
for(Thread t : list) {
t.start();
}
}
}
知识点:
Atomic系列的类能够保障多线程原子性的操作,不能保障分布式多节点的原子性,其只能保障本节点多线程原子性。
AtomicReference应用:
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name,int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "[name:"+this.name+",age:"+this.age+"]";
}
}
public class UseAtomicReference2 {
//普通引用
private static Person person;
//原子性引用
private static AtomicReference<Person> aRperson;
public static void main(String[] args) throws InterruptedException {
person = new Person("Tom",18);
aRperson = new AtomicReference<Person>(person);
System.out.println("Atomic Person is" + aRperson.get().toString());
Thread t1 = new Thread(new Task1());
Thread t2 = new Thread(new Task2());
t1.start();
t2.start();
t1.join();
t2.join();
Thread.sleep(100);
System.out.println("Now Person is" + aRperson.get().toString());
}
static class Task1 implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
//person.setAge(19);
//person.setName("Tom1");
//compareAndSet 即 C A S 原子操作
System.out.println("ret = "+
aRperson.compareAndSet(
aRperson.get(),
new Person("Tom",aRperson.get().getAge()+1)
));
System.out.println("Thread1 Atomic References"+aRperson.toString());
}
}
static class Task2 implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
//person.setAge(20);
//person.setName("Tom2");
System.out.println("ret = "+
aRperson.compareAndSet(
aRperson.get(),
new Person("Tom",aRperson.get().getAge()+2)
));
System.out.println("Thread2 Atomic References"+aRperson.toString());
}
}
}