package com.dome;
public class Thread01 {
private volatile static int a =10; Thread td1 = new Thread(){ public void run(){ for(int i=0;i<3;i++){ a = a+1; System.out.println(i+"td1:="+a); } } }; Thread td2 = new Thread(){ public void run(){ for(int i=0;i<3;i++){ a -=1; System.out.println(i+"td2:="+a); } } }; public static void main(String[] args) { Thread01 th = new Thread01(); th.td1.start(); th.td2.start(); }
}
0td1:=9
0td2:=9
1td1:=10
1td2:=9
2td1:=10
2td2:=9
a = a + 1
, a = a - 1
这样的语句,事实上涉及了 读取-修改-写入 三个操作:
读取变量到栈中某个位置
对栈中该位置的值进行加 (减)1
将自增后的值写回到变量对应的存储位置
因此虽然变量 a 使用 volatile
修饰,但并不能使涉及上面三个操作的 a = a + 1
,a = a - 1
具有原子性。为了保证同步性,需要使用 synchronized
:
public class Thread01 { private volatile static int a = 10; Thread td1 = new Thread() { public void run() { for (int i = 0; i < 3; i++) { synchronized (Thread01.class) { a = a + 1; System.out.println(i + "td1:=" + a); } } } }; Thread td2 = new Thread() { public void run() { for (int i = 0; i < 3; i++) { synchronized (Thread01.class) { a -= 1; System.out.println(i + "td2:=" + a); } } } }; public static void main(String[] args) { Thread01 th = new Thread01(); th.td1.start(); th.td2.start(); } }
某次运行结果:
(td1 出现的地方,a 就 +1;td2 出现的地方,a 就 -1)