public class Test implements Runnable {
private static volatile int count = 0 ; //使用 volatile 修饰基本数据内存不能保证原子性
//private static AtomicInteger count = new AtomicInteger() ;
public void run() {
for (int i=0;i<10000 ;i++){
count ++ ;
//count.incrementAndGet() ;
}
}
public static void main(String[] args) throws InterruptedException {
Test volatileInc = new Test() ;
Thread t1 = new Thread(volatileInc,"t1") ;
Thread t2 = new Thread(volatileInc,"t2") ;
t1.start();
//t1.join();
t2.start();
//t2.join();
for (int i=0;i<10000 ;i++){
count ++ ;
//count.incrementAndGet();
}
System.out.println("最终Count="+count);
}
}
当我们三个线程(t1,t2,main)同时对一个 int
进行累加时会发现最终的值都会小于 30000。
这是因为虽然
volatile
保证了内存可见性,每个线程拿到的值都是最新值,但count ++
这个操作并不是原子的,这里面涉及到获取值、自增、赋值的操作并不能同时完成。
-
所以想到达到线程安全可以使这三个线程串行执行(其实就是单线程,没有发挥多线程的优势)。
-
也可以使用
synchronize
或者是锁的方式来保证原子性。 -
还可以用
Atomic
包中AtomicInteger
来替换int
,它利用了CAS
算法来保证了原子性。