【java疑问】while循环时候条件被其他进程改变后不会刷新

口口口S口口口 2018-11-10 11:46:06
今天给自己的项目进行debug的时候没有考虑到异步的顺序,导致对某个值进行操作的时候异步还没有返回。这里我通常使用while循环等待异步完成然后修改条件,但是这里我遇到很奇怪的现象,希望诸位可以给我解答.
程序代码有点多因此这里我只将这个例子单独修改成demo

public class Task {

private static int flag = -1;

public static void main(String[] args) {
new Thread(new ChangeTask()).start();
while (flag == -1){}
System.out.println("debug");
}

static class ChangeTask implements Runnable {
try {
Thread.sleep(3000);
} catch (Exception e) {}
flag = 1;
}

}

此时就算ChangeTask将flag改变后主线程的while条件还是无法跳出循环。
以下两种写法也不行

/* 方法1 */
for (;flag == -1;){}

/* 方法2 */
do {

} while(flag == -1);


如果将while修改成这样

while (true) {
if (flag != -1) break;
}

依然不行。
如果将语句修改成这样添加输出语句

while (flag == -1) {
System.out.println("debug");
}

却可以。
如果用Lock的话由于我实际的操作都是在一个线程中进行的,且该线程是主线程,因此Lock无法使用.

为什么会有这么奇怪的现象?可能是我java专业知识不过关吧。想请问各位有没有解决办法。

...全文
202 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
qybao 2018-11-12
  • 打赏
  • 举报
回复
没有完整代码不好分析,按理说现在的CPU不应该发生你所描述的情况,你可以参考volatile变量
引用 3 楼 qq_33710794 的回复:
果然加了Thread.yield();可以了,感谢,后面是我个人的一些疑惑您可以看心情解答。 yield()只是会将CPU资源让给其他线程执行,但是在将flag修改之后while中条件还是无法跳出,即while中的flag == 1还是为true,这个情况是因为什么而产生的呢?
  • 打赏
  • 举报
回复
引用 2 楼 qybao 的回复:
没问题吧?你的Runnale没实现run方法,能编译通过吗
static class ChangeTask implements Runnable {
        public void run() {
            try {
                Thread.sleep(3000);
            } catch (Exception e) {}
            flag = 1;
        }
    }
另外,防止你的while(flag == -1)过多占用CPU,你可以yield一下 while (flag == -1){} 改成 while(flag == -1) {Thread.yield();}
果然加了Thread.yield();可以了,感谢,后面是我个人的一些疑惑您可以看心情解答。 yield()只是会将CPU资源让给其他线程执行,但是在将flag修改之后while中条件还是无法跳出,即while中的flag == 1还是为true,这个情况是因为什么而产生的呢?
qybao 2018-11-12
  • 打赏
  • 举报
回复
没问题吧?你的Runnale没实现run方法,能编译通过吗
static class ChangeTask implements Runnable {
        public void run() {
            try {
                Thread.sleep(3000);
            } catch (Exception e) {}
            flag = 1;
        }
    }
另外,防止你的while(flag == -1)过多占用CPU,你可以yield一下 while (flag == -1){} 改成 while(flag == -1) {Thread.yield();}
翻身已碰头 2018-11-12
  • 打赏
  • 举报
回复
等待异步执行完成在继续后续逻辑的话可以使用callable代替runnable,然后future.get()会自动阻塞当前线程直到异步完成

50,528

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧