1.前言
-
java.util.concurrent.atomic 的包里有AtomicBoolean, AtomicInteger, AtomicLong, AtomicLongArray,
AtomicReference等原子类的类,主要用于在高并发环境下的高效程序处理,来帮助我们简化同步处理。 -
在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。
2.基础用法
(1)创建一个AtomicInteger
System.out.println(atomicInteger.get());
//输出 : 123
(2)创建一个不传值的,默认值为0
AtomicInteger atomicInteger = new AtomicInteger();
System.out.println(atomicInteger.get());
//输出: 0
(3)获取和赋值
atomicInteger.get(); //获取当前值
atomicInteger.set(999); //设置当前值
(4)compareAndSet
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(0);
System.out.println(atomicInteger.get());
int expectedValue = 123;
int newValue = 234;
Boolean b =atomicInteger.compareAndSet(expectedValue, newValue);
System.out.println(b);
System.out.println(atomicInteger);
}
//输出结果为: 0 false 0
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(123);
System.out.println(atomicInteger.get());
int expectedValue = 123;
int newValue = 234;
Boolean b =atomicInteger.compareAndSet(expectedValue, newValue);
System.out.println(b);
System.out.println(atomicInteger);
}
//输出结果为: 123 true 234
由上可知该方法表示,atomicInteger的值与expectedValue相比较,如果不相等,则返回false,
atomicInteger原有值保持不变;如果两者相等,则返回true,atomicInteger的值更新为newValue
(5)getAndAdd()方法与AddAndGet方法
AtomicInteger atomicInteger = new AtomicInteger(123);
System.out.println(atomicInteger.get()); //123
System.out.println(atomicInteger.getAndAdd(10)); //123 获取当前值,并加10
System.out.println(atomicInteger.get()); //133
System.out.println(atomicInteger.addAndGet(10)); //143 获取加10后的值,先加10
System.out.println(atomicInteger.get()); //143
(6)getAndDecrement()和DecrementAndGet()方法
AtomicInteger atomicInteger = new AtomicInteger(123);
System.out.println(atomicInteger.get()); //123
System.out.println(atomicInteger.getAndDecrement()); //123 获取当前值并自减
System.out.println(atomicInteger.get()); //122
System.out.println(atomicInteger.decrementAndGet()); //121 先自减再获取减1后的值
System.out.println(atomicInteger.get()); //121
3.自增问题
(1)使用普通Integer++
public class Counter {
public volatile static int count = 0;
public static void inc(){
try{
Thread.sleep(1); //延迟1毫秒
}catch (InterruptedException e){ //catch住中断异常,防止程序中断
e.printStackTrace();
}
count++;//count值自加1
}
public static void main(String[] args) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(100);
for(int i=0;i<100;i++){
new Thread(new Runnable() {
@Override
public void run() {
Counter.inc();
latch.countDown();
}
}).start();
}
latch.await();
System.out.println("运行结果:"+Counter.count);
}
}
//运行结果:98
(2)使用synchronized解决线程安全性问题
import java.util.concurrent.CountDownLatch;
/**
* created by guanguan on 2017/10/23
**/
public class Counter {
public volatile static Integer count = 0;
public synchronized static void inc(){
try{
Thread.sleep(1); //延迟1毫秒
}catch (InterruptedException e){ //catch住中断异常,防止程序中断
e.printStackTrace();
}
count++;//count值自加1
}
public static void main(String[] args) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(100);
for(int i=0;i<100;i++){
new Thread(new Runnable() {
@Override
public void run() {
Counter.inc();
latch.countDown();
}
}).start();
}
latch.await();
System.out.println("运行结果:"+Counter.count);
}
}
//运行结果:100
(3)使用AtomicInteger 非阻塞算法来实现并发控制
public class Counter {
public static AtomicInteger count = new AtomicInteger(0);
public static void inc(){
try{
Thread.sleep(1); //延迟1毫秒
}catch (InterruptedException e){ //catch住中断异常,防止程序中断
e.printStackTrace();
}
count.getAndIncrement();//count值自加1
}
public static void main(String[] args) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(100);
for(int i=0;i<100;i++){
new Thread(new Runnable() {
@Override
public void run() {
Counter.inc();
latch.countDown();
}
}).start();
}
latch.await();
System.out.println("运行结果:"+Counter.count);
}
}
//运行结果: 100
4.总结
使用AtomicInteger是非常的安全的,而且因为AtomicInteger由硬件提供原子操作指令实现的。在非激烈竞争的情况下,开销更小,速度更快。