问题1:Volatile有什么作用?
package com.victor.hello; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class VolatileTest { private static volatile int volatileCounter = 0; private static int noneVolatileCounter = 0; public static void main(String[] args){ final ScheduledExecutorService service = Executors.newScheduledThreadPool(10); for(int i =0;i<10;i++){ service.scheduleAtFixedRate(new Runnable(){ @Override public void run() { String threadName = Thread.currentThread().getName(); volatileCounter++; sleep(); volatileCounter--; noneVolatileCounter++; sleep(); noneVolatileCounter--; System.out.println(volatileCounter+" "+noneVolatileCounter+" ["+threadName+"]"); } }, 0, 3, TimeUnit.SECONDS); } } private static void sleep(){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }
为了体验Volatile这个关键字的作用,我写了一个测试方法。两个int类型的变量,分别用volatile和不用volatile修饰。先做一个++的操作,再做一个--的操作。之间休息0.1秒。起十个线程,定时的操作。
有经验的同学一看就知道,这么操作觉得线程不安全。让我们看看执行的结果。
0 9 [pool-1-thread-9]
0 8 [pool-1-thread-7]
0 7 [pool-1-thread-5]
0 6 [pool-1-thread-3]
0 5 [pool-1-thread-1]
0 4 [pool-1-thread-2]
0 3 [pool-1-thread-4]
0 2 [pool-1-thread-8]
0 1 [pool-1-thread-6]
0 0 [pool-1-thread-10]
1 9 [pool-1-thread-3]
1 8 [pool-1-thread-5]
1 7 [pool-1-thread-9]
1 6 [pool-1-thread-7]
1 5 [pool-1-thread-2]
1 4 [pool-1-thread-4]
1 3 [pool-1-thread-1]
1 2 [pool-1-thread-6]
1 1 [pool-1-thread-8]
1 0 [pool-1-thread-10]
1 9 [pool-1-thread-1]
1 8 [pool-1-thread-3]
1 7 [pool-1-thread-5]
1 5 [pool-1-thread-9]
1 5 [pool-1-thread-7]
1 4 [pool-1-thread-4]
1 3 [pool-1-thread-8]
1 2 [pool-1-thread-2]
1 1 [pool-1-thread-6]
1 0 [pool-1-thread-10]
1 9 [pool-1-thread-7]
1 8 [pool-1-thread-5]
1 7 [pool-1-thread-9]
1 6 [pool-1-thread-8]
1 5 [pool-1-thread-4]
1 4 [pool-1-thread-1]
1 3 [pool-1-thread-2]
1 2 [pool-1-thread-3]
1 1 [pool-1-thread-6]
1 0 [pool-1-thread-10]
1 9 [pool-1-thread-3]
1 8 [pool-1-thread-7]
1 7 [pool-1-thread-5]
1 6 [pool-1-thread-4]
1 5 [pool-1-thread-8]
1 4 [pool-1-thread-1]
1 3 [pool-1-thread-9]
1 3 [pool-1-thread-2]
1 1 [pool-1-thread-6]
1 1 [pool-1-thread-10]
1 9 [pool-1-thread-7]
1 8 [pool-1-thread-3]
1 7 [pool-1-thread-9]
1 7 [pool-1-thread-5]
1 6 [pool-1-thread-1]
1 5 [pool-1-thread-4]
1 4 [pool-1-thread-8]
1 3 [pool-1-thread-2]
1 2 [pool-1-thread-6]
1 1 [pool-1-thread-10]
1 10 [pool-1-thread-4]
1 9 [pool-1-thread-7]
1 8 [pool-1-thread-1]
1 7 [pool-1-thread-3]
1 6 [pool-1-thread-8]
1 5 [pool-1-thread-2]
1 4 [pool-1-thread-9]
1 2 [pool-1-thread-5]
1 2 [pool-1-thread-10]
1 1 [pool-1-thread-6]
可见,每次并发的时候。Volatile的修改都能迅速的让其他线程感知到。也就是线程间的可见性。
但几次并发以后,它就忍不住线程不安全了。可见并没有保证线程的安全。
关于Volatile关键字的研究