Atomic,英文的意思是“原子性的”,JDK在java.util.concurrent.atomic包中给我们提供了一组原子操作类,直接看一个例子,就能明白。package test14;
import java.util.concurrent.atomic.AtomicInteger;
public class IntegerTest {
public static void main(String[] args) throws InterruptedException {
AddTask task = new AddTask(1);
Thread[] threads = new Thread[10];
for(int i = 0 ; i
threads[i] = new Thread(task);
threads[i].start();
}
for(Thread t : threads){
t.join();
}
System.out.println("最终结果为:");
task.display();
}
}
class AddTask implements Runnable{
private int i = 0;
//private AtomicInteger atomic ;
public AddTask(int i){
this.i = i;
//this.atomic = new AtomicInteger(i);
}
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i = i + 1;
//atomic.incrementAndGet();
}
void display(){
System.out.println("i = " + i);
//System.out.println("atomicInteger = " + atomic);
}
}
当变量为普通int型时,由于i = i + 1这个操作并不是原子性,导致并发问题,往往结果<= 11,如果使用AtomicInteger时,就会始终得到11了。
在java.util.concurrent.atomic包下,提供了Integer/Long/Boolean类型的原子操作类,还提供了数组/引用类型的原子操作类。下面,以AtomicInteger为例,简单分析下原子操作类的实现原理。
注意在AtomicInteger类中的成员变量:private volatile int value;
注意用了volatile修饰,在并发时,其他线程可见!
我们分析一个方法就可以了,以incrementAndGet()为例:
注意get()返回的就是那个成员变量value,实际上利用compareAndSet进行对比和修改,如果current和当前value进行比对,如果一致,说明老值一样,并没有其他线程修改过,那么可以将老值设置为next,否则死循环,尝试修改!其实这就是所谓的CAS机制。