java.util.concurrent.atomic提供了一组原子类型操做。如AtomicInteger提供了java
int addAndGet(int delta) int incrementAndGet() int get() int compareAndGet()
Atomic类能够实现<font color="blue">无锁(lock-free)的线程安全(thread-safe)访问</font>编程
<p style="color: red;background-color: yellow">原理:CAS(Compare and Set)若是AtomicInteger实例的值是prev,就替换为next,返回true;不然,返回false</p> ```#java /* * 在这个操做中,若是AtomicInteger当前的值是prev,就更新为next,返回true,终止循环; * 若是AtomicInteger当前的值不等于prev,就什么也不作,返回false,继续循环。 */ public int add1AndGet(AtomicInteger var){ int prev, next; do{ prev = var.get(); //以后其余的线程修改了prev的值,也不影响结果 next = prev + 1; }while ( ! var.compareAndSet(prev, next)); return prev; } ``` 利用CAS操做,能够保证,即时在do while循环中,其余的线程在prev = var.get()后修改了AtomicInteger的值,最终结果也必定是正确的。 ### 1.2 incrementAndGet 一般不须要直接使用do...while..来调用compileAndGet,而是用incrementAndGet()这种封装的方法。 ```#java AtomicLong var = new AtomicLong(0); public long getNextId(){ //多线程安全的id序列生成器 return var.incrementAndGet(); } ``` ## 2.示例 ```#java import java.util.concurrent.atomic.AtomicInteger;安全
class Counter{ private AtomicInteger value = new AtomicInteger(); //add、dec、get再也不使用synchronized或ReentrantLock加锁,由于Atomic自己就是原子操做 public int add(int m){ return this.value.addAndGet(m); } public int dec(int m){ return this.value.addAndGet(-m); } public int get(){ return this.value.get(); } } public class Main{ final static int LOOP = 100; public static void main(String[] args) throws InterruptedException{ Counter counter = new Counter(); Thread t1 = new Thread(){ public void run(){ for(int i=0;i<LOOP;i++) { counter.add(1); } } }; Thread t2 = new Thread(){ public void run(){ for(int i=0;i<LOOP;i++){ counter.dec(1); } } }; t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(counter.get()); System.out.println("END"); } }多线程
<img src="https://img2018.cnblogs.com/blog/1418970/201906/1418970-20190613170947374-25418412.png" width="500" /> ## 3.总结: 使用java.util.atomic提供的原子操做能够简化多线程编程 * AtomicInteger/AtomicLong/AtomicArray * 原子操做实现了无锁的线程安全 * 适用于计数器、累加器