多线程情况下,怎样确保对同一变量的改变出现一致性问题
-
使用synchronized关键字
比如:对num变量进行操作,如果没有synchronized 关键字,即使是使用volatile修饰变量,输出的值也会小于100000,因为volatile虽然能够保证可见性及顺序性,但是不能保证变量的原子性。
private static int num = 0;
private static synchronized void increment() {
num++;
}
-
使用Lock锁
private static int num = 0;
private static Lock lock = new ReentrantLock();
public static void increment() {
lock.lock();
num++;
lock.unlock();
}
-
使用Atomic原子类
private static AtomicInteger ai = new AtomicInteger();
public static void increment() {
ai.getAndIncrement();
}
多线程情况下调用:
//线程调用
public static void threadUse() {
long time1 = new Date().getTime();
for(int i=0;i<10;i++) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int j=0;j<10000;j++) {
increment();
}
}
}).start();
}
//确保所有线程调用完毕
while(Thread.activeCount()>1)
Thread.yield(); //继续执行此线程
System.out.println("time="+(new Date().getTime()-time1)); //执行所用时间
}
分别调用上述三种情况,输出都是100000,但是执行所花的时间是不同的,发现synchronized和lock使用的时间基本相同,使用Atomic原子类所花时间相对是两种的一半,但是当执行量越来越大的时候发现使用synchronized所花的时间还越来越(JDK8)。