AtomicInteger,这是java提供的一个原子操作Integer的类,这在我眼里还是一个稀客,可能是不怎么感兴趣,以至于一直当作简单的volatile,这也是我的拙见。其实这家伙还是挺好用的,在常见的场景中,如count++或++count,这在java多线程的使用中是不安全的,而AtomicInteger属于原子操作(线程安全),可以在下面的例子中看出来。
package org.jan.java.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* 关于count++在多线程调用情况下
*
* @author jan
*/
public class Counter {
private volatile int count = 0;
/**
* 为了保证数据的准确性,多线程的情况下需要加上synchronized关键字</br>
* 否则会出现出乎预料的结果 这也是线程安全的重要体现
*/
public void increment() {
count++;
}
private int getCount() {
return count;
}
/**
* 这里模拟一个递增的任务,递增目标为100W
*/
public static void main(String[] args) throws InterruptedException {
final Counter counter = new Counter();
// final AtomicCounter counter = new AtomicCounter();
int workCount = 1000000;
ExecutorService executor = Executors.newFixedThreadPool(10);
long start = System.currentTimeMillis();
for (int i = 0; i < workCount; i++) {
Runnable runnable = new Runnable() {
@Override
public void run() {
counter.increment();
}
};
executor.execute(runnable);
}
// 关闭启动线程,执行未完成的任务
executor.shutdown();
// 等待所有线程完成任务,完成后才继续执行下一步
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
System.out.println("耗时:" + (System.currentTimeMillis() - start) + "ms");
System.out.println("执行结果:count=" + counter.getCount());
}
}
它的结果不是我们预料的100 0000 .通常我们需要加上在count++时 加上synchronized关键字,保证他的正确性。
如果我们换个方式,用AtomicInteger来替换count++,怎么做呢?
public class AtomicCounter {
private AtomicInteger count = new AtomicInteger(0);
// 使用AtomicInteger之后,不需要加锁,也可以实现线程安全。
public void increment() {
//获取当前的值并自增
count.incrementAndGet();
}
/**
* 获取当前的值
* @return
*/
public int getCount() {
return count.get();
}
//递减
public void deIncrement(){
count.decrementAndGet();
}
}
把最开始的代码里的Counter对象换成我们的AtomicCounter类的对象,试试他的方法,我们发现,结果就保证了100W!
AtomicInteger 还有其他的一些方法,查一下Api就行了。而且也不是说只有Integer有这么个原子操作的类,这里不是重点,有兴趣就自己百度去吧。
//获取当前的值
publicfinal int get()
//取当前的值,并设置新的值
publicfinal int getAndSet(intnewValue)
//获取当前的值,并自增
publicfinal int getAndIncrement()
//获取当前的值,并自减
publicfinal int getAndDecrement()
//获取当前的值,并加上预期的值
publicfinal int getAndAdd(intdelta)
你说他就这么一个特点,并不是很吸引人?
他的性能貌似也挺给力的,就如最开始的那个代码把,我看了一下啊,在count++ 方法加上synchronized字段后与 atomicInteger的increment方法相比较,atomicInteger的性能貌似比前者更快!有兴趣的可以自己比较一下看看。
嗯。
最后,感谢以下博文的鼎立奉献,感谢百度祖师爷的全力帮助