git地址:github.com/fw103699437…
不具有原子性
public class NotAtomicDemo {
volatile static int k;
// static int k = 0;
public static void main(String[] args) {
int num = 100000;
CountDownLatch countDownLatch = new CountDownLatch(num);
for (int i = 0; i < num; i++) {
new Thread(()->{
k++;
countDownLatch.countDown();
}).start();
}
try {
countDownLatch.await();
System.out.println(k);
} catch (Exception e) {
e.printStackTrace();
}
}
}
複製程式碼
99994
顯然volatile不具有原子性,這個不用多說
Process finished with exit code 0
複製程式碼
具有可見性
public class VisibilityDemo {
static int k = 0;
// volatile static int k = 0;
public static void main(String[] args) {
new Thread(()->{
while (true){
if(k>=5){
System.out.println("______________k可見了" + new Date(System.currentTimeMillis()) +" " + k);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(()->{
while(true){
k++;
System.out.println("k++" + new Date(System.currentTimeMillis()) + " " + k);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
複製程式碼
k++Thu Dec 05 18:12:34 CST 2019 1
k++Thu Dec 05 18:12:35 CST 2019 2
k++Thu Dec 05 18:12:36 CST 2019 3
k++Thu Dec 05 18:12:37 CST 2019 4
k++Thu Dec 05 18:12:38 CST 2019 5
k++Thu Dec 05 18:12:39 CST 2019 6
k++Thu Dec 05 18:12:40 CST 2019 7
k++Thu Dec 05 18:12:41 CST 2019 8
k++Thu Dec 05 18:12:42 CST 2019 9
k++Thu Dec 05 18:12:43 CST 2019 10
複製程式碼
說明第一個執行緒沒有意識到k已經>=5了,而且過了很久都沒有意識到,多次實驗均如此,
加上volatile之後
// static int k = 0;
volatile static int k = 0;
複製程式碼
k++Thu Dec 05 18:15:07 CST 2019 1
k++Thu Dec 05 18:15:08 CST 2019 2
k++Thu Dec 05 18:15:09 CST 2019 3
k++Thu Dec 05 18:15:10 CST 2019 4
k++Thu Dec 05 18:15:11 CST 2019 5
______________k可見了Thu Dec 05 18:15:11 CST 2019 5
______________k可見了Thu Dec 05 18:15:12 CST 2019 6
k++Thu Dec 05 18:15:12 CST 2019 6
______________k可見了Thu Dec 05 18:15:13 CST 2019 7
k++Thu Dec 05 18:15:13 CST 2019 7
複製程式碼
第一個執行緒可以意識到k>5了,多次試驗均是如此。
還有一些沒想明白的問題
while (true){
//加上之後k居然可見了
System.out.println("sout");
if(k>=5){
複製程式碼
在while和if之間加上一句之後,在五秒後,第一個執行緒就可以看到k更新了,,多次實驗均如此
if(k>=5){
System.out.println("______________k可見了" + new Date(System.currentTimeMillis()) +" " + k);
//拿到if外 也可見
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
複製程式碼
或者把sleep放到if外,五秒後,第一個執行緒也可以看到k更新,多次實驗均如此
這就有點想不通了。
結論
雖然有想不通的地方,不過在原子性,可見性上還是有一些收穫的,volatile可以立即看到新的值(可見性),但是不具有原子性。