Atomic系列类别
Atomic系列类封装了一系列的基础类型和对象操作,其主要目的就是为了实现原子性,主要核心类如下
- AtomicInteger
- AtomicLong
- AtomicBoolean
- AtomicIntegerArray
- AtomicLongArray
- AtomicReference 原子性的引用对象
- 在对Atomic类操作的时候,如果是有多个操作执行,那么就是非原子性的,需要加synchronized进行修饰,保证Atomic类操作整体原子性
package com.example.core.cas;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;public class UseAtomic {private static /* int count = 0*/AtomicInteger count = new AtomicInteger(0);public synchronized int add(){//使用synchronized关键字使得多个操作合并在一起,形成一个整体//return count.addAndGet(10);将+1+2+3+4代替+10,模拟多个操作count.addAndGet(1);count.addAndGet(2);count.addAndGet(3);count.addAndGet(4);return count.get();}public static void main(String[] args) {UseAtomic ua = new UseAtomic();List<Thread> list = new ArrayList<>();//如果使用atomicInteger最终结果一定是1000for (int i=0;i<100;i++){list.add(new Thread(new Runnable() {@Overridepublic void run() {System.out.println("累计结果:"+ua.add());}}));}for(Thread t:list){t.start();}}
}
另一个例子
- Person.class
package com.example.core.cas;public class Person {private String name;private int age;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;}public String toString() {return "[name: " + this.name + ", age: " + this.age + "]";}
}
- 多个线程抢占同一份资源,会造成问题
package com.example.core.cas;public class UseAtomicReference1 {private static Person person;public static void main(String[] args) throws InterruptedException {person = new Person("Tom", 18);System.out.println("Person is " + person.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 " + person.toString());}static class Task1 implements Runnable {public void run() {person.setAge(19);person.setName("Tom1");System.out.println("Thread1 Values "+ person.toString());}}static class Task2 implements Runnable {public void run() {person.setAge(20);person.setName("Tom2");System.out.println("Thread2 Values "+ person.toString());}}}
- 使用Atomic,如果两个线程逐次访问并修改资源,可以保证数据一致性;如果同时访问,其中一个就会返回false,不修改数据
- 避免产生并发行
package com.example.core.cas;import java.util.concurrent.atomic.AtomicReference;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(500);System.out.println("Now Atomic Person is " + aRperson.get().toString());}static class Task1 implements Runnable { public void run() {System.err.println("ret = " + // C A S 原子操作aRperson.compareAndSet( //10ms aRperson.get(), //如果满足我的预期,就进行修改;不满足就不修改new Person("Tom", aRperson.get().getAge() + 1)));System.out.println("Thread1 Atomic References "+ aRperson.get().toString());}}static class Task2 implements Runnable {public void run() {System.err.println("ret = " + aRperson.compareAndSet( //8msaRperson.get(), //如果满足我的预期,就进行修改;不满足就不修改new Person("Tom", aRperson.get().getAge() + 2)));System.out.println("Thread2 Atomic References "+ aRperson.get().toString());}}
}