java 线程,while()括号中的判断为false为什么还会执行while循环体呢

程序如下package tql.thread;import java.util.Date;public class TestInterrupt { public static void main(String[] args) { MyThread mt = new MyThread(); mt.start(); try { Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " is running"); } catch (InterruptedException e) { } mt.flag = false; }}class MyThread extends Thread { boolean flag = true; public void run() { while (flag) { System.out.println(Thread.currentThread().getName() + " is running"); System.out.println("----" + new Date() + "----"); try { sleep(2000); System.out.println(flag); System.out.println("***" + Thread.currentThread().getName() + " is running" + "***"); } catch (InterruptedException e) { break; } } }}执行结果如下:Thread-0 is running----Fri Dec 19 20:09:38 CST 2008----main is runningfalse***Thread-0 is running***我是想问一下,当主线程执行后,由mt.flag = false,将flag的值设为false了,然后Thread-0执行,可是while(flag)的时候,flag都已经为false了,为什么while里面的语句还会继续执行?谢谢大家啊
2026年09月22日 00:56
有4个网友回答
网友(1):

这个问题要看几率

买彩票中500W的几率能达到你想要的效果,呵呵

问题主要是这样的:

这个和你调用sleep基本上没多大关系

main线程里面一开始就启动了子线程,这时候2个线程同时运行,去抢占CPU时间片

大多数时候,子线程一直执行,不停的打印,当子线程执行到下面这条语句:
System.out.println("----" + new Date() + "----");
main线程抢到了时间片,所以main线程又开始执行,main执行期间正好把flag 设置为false

然后子线程抢到时间片,开始执行,打印flag,很明显,打印的结果是false,因为flag的值已经被main线程修改了,这里的关键点就是在子线程打印flag的值的时候,子线程根本就没有进行while的判断,因为子线程上次执行的时候已经判断通过了,所以看上去子线程有点不听话,多执行了一次

其实如果“flag都已经为false了,while里面的语句还会继续执行”这句话成立的话,你看到的打印效果肯定不只5行,肯定是死循环一直打印,对吧

简单的修改可以这样:
public class TestInterrupt {
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();
try {
// Thread.sleep(1000);
System.out
.println(Thread.currentThread().getName() + " is running");
} catch (Exception e) {
}
synchronized (mt.flag) {
mt.flag = false;
}
}
}

class MyThread extends Thread {
Boolean flag = true;

public void run() {

while (true) {
synchronized (flag) {
if(!flag) {
System.out.println("flag is false, exit");
break;
}
System.out.println(Thread.currentThread().getName()
+ " is running");
System.out.println("----" + new Date() + "----");
try {
// sleep(2000);
System.out.println(flag);
System.out.println("***" + Thread.currentThread().getName()
+ " is running" + "***");
} catch (Exception e) {
break;
}
}
}
}
}

貌似可以实现,没有测试

网友(2):

public class TestInterrupt {
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();
try {
Thread.sleep(1000);//1.main线程sleep,跳到mt线程。
System.out.println(Thread.currentThread().getName()//4.跳回来继续
+ " is running");
} catch (InterruptedException e) {
}
mt.flag = false;//5.令flag = false,main线程结束,跳到mt线程
}
}

class MyThread extends Thread {
boolean flag = true;

public void run() {
while (flag) {//2.此时flag为true,进入循环 //7.判断flag为false,不循环了。。。
System.out.println(Thread.currentThread().getName()
+ " is running");
System.out.println("----" + new Date() + "----");
try {
sleep(2000);//3.mt线程sleep,跳到main线程
System.out.println(flag);//6.跳回来继续
System.out.println("***" + Thread.currentThread().getName()
+ " is running" + "***");
} catch (InterruptedException e) {
break;
}
}
}
}

网友(3):

其实表面上你是设置flag为false了,但是其实在线程里面获取到flag是true,这是因为这个变量没有加线程同步引起的,你可以加一个set方法,然后这个set方法使用synchronized修饰,或者在线程类里面使用监视器和同步代码块

网友(4):

你while循环后面的花括符好像错了,位置好像错了!就在break语句后面..