多线程并发解决方案(原子变量的使用)
2018-04-15 本文已影响20人
乘风破浪的姐姐
下面是一个没有控制并发的计数器:
public class Counter implements Runnable {
private static int count;
public void run() {
System.out.println(Thread.currentThread().getName() + ":" + (++count));
}
public static void main(String[] args){
Counter counter = new Counter();
Thread t1 = new Thread(counter);
Thread t2 = new Thread(counter);
Thread t3 = new Thread(counter);
Thread t4 = new Thread(counter);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
每次执行输出的结果不一样,如:
Thread-1:2
Thread-0:1
Thread-2:3
Thread-3:3
从Java内存模型的角度来看,简单的counter++的执行过程其实分为如下三步:
第一步,从主内存中加载counter的值到线程工作内存
第二步,执行加1运算
第三步,把第二步的执行结果从工作内存写入到主内存
为了预防并发情况的产生,可以使用原子变量java.util.concurrent.atomic包下的类
public class Counter implements Runnable {
private final AtomicInteger count = new AtomicInteger(0);
public void run() {
System.out.println(Thread.currentThread().getName()
+ ":" + count.incrementAndGet());
}
public static void main(String[] args){
Counter counter = new Counter();
Thread t1 = new Thread(counter);
Thread t2 = new Thread(counter);
Thread t3 = new Thread(counter);
Thread t4 = new Thread(counter);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
其中自增自减方法说明:
incrementAndGet(),返回新值(即加1后的值)
getAndIncrement(),返回旧值(即加1前的原始值)
decrementAndGet(),返回新值(即减1后的值)
getAndDecrement(),返回旧值(即减1前的原始值)