public class test {
private volatile static int a = 1;
private volatile static int flag = 1;
public static void main(String[] args) {
Thread t1 = new Thread(()->{
for(int i=0; i<10; i++){
try {
Thread.sleep(500);
// synchronized (test.class){
System.out.println("t1前: "+a); //包括字符串拼接
a = 2; //t1与t2这三句话可能互相穿插(线程间互相穿插不属于指令重排)。所以用synchonized才能解决并发问题
System.out.println("t1后: "+a);
// }
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(()->{
for(int i=0; i<10; i++){
try {
Thread.sleep(500);
// synchronized (test.class){
System.out.println("t2前: "+a);
a = 3;
System.out.println("t2后: "+a);
// }
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
//测试volatile可见性
Thread t3 = new Thread(()->{
while(flag == 1){}
System.out.println("退出循环");
});
Thread t4 = new Thread(()->{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = 0;
});
t1.start();
t2.start();
// t3.start();
// t4.start();
}
}
t1前: 1 t1,t2先执行了第一次输出,再进行赋值,或者t2输出字符串拼接的过程中,t1进行了赋值
t2前: 1
t2后: 3
t1后: 2
t2前: 3
t2后: 3
t1前: 3
t1后: 2
t2前: 2
t2后: 3
t1前: 2
t1后: 2
t2前: 2
t2后: 3
t1前: 2
t1后: 2
t1前: 2
t1后: 2
t2前: 2
t2后: 3
t1前: 3
t1后: 2
t2前: 3
t2后: 3
t2前: 3
t2后: 3
t1前: 3
t1后: 2
t2前: 2
t2后: 3
t1前: 2
t1后: 2
t1前: 2
t1后: 2
t2前: 2
t2后: 3
t1前: 3
t1后: 2
t2前: 3
t2后: 3