1.加上volatile关键字内存可见性,线程t1结束,不加volatile线程t1死循环无法结束。
import java.util.concurrent.TimeUnit;
public class T01_withVolitile {
private volatile boolean stop=false;
public static void main(String[] args) throws Exception{
T01_withVolitile c = new T01_withVolitile();
new Thread(()->{
while (!c.stop){
}
System.out.println("线程t1结束");
},"t1").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
c.stop=true;
},"t2").start();
}
}
2.Thread.sleep()
与1的区别是没有关键字volatile,循环中加了sleep()语句,线程1可以结束。原因:线程sleep时是阻塞状态,时间结束时变为可运行状态,获得cpu运行权限时从主内存中读取数据,线程1读取到更新后的值跳出循环结束线程。
import java.util.concurrent.TimeUnit;
public class T01_withVolitile {
private boolean stop = false;
public static void main(String[] args) throws Exception {
T01_withVolitile c = new T01_withVolitile();
new Thread(() -> {
while (!c.stop) {
try {
Thread.sleep(1);
} catch (Exception e){}
} System.out.println("线程t1结束");
}, "t1").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
c.stop = true;
}, "t2").start();
}
}
3.System.out.println()
与1的区别是没有关键字volatile 循环中加了打印语句。线程1可以结束。原因:System.out.println()代码是加锁的保证内存可见性
import java.util.concurrent.TimeUnit;
public class T01_withVolitile {
private boolean stop=false;
public static void main(String[] args) throws Exception{
T01_withVolitile c = new T01_withVolitile();
new Thread(()->{
while (!c.stop){
System.out.println("a");
}
System.out.println("线程t1结束");
},"t1").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
c.stop=true;
},"t2").start();
}
}