首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中线程间共享变量的问题(11)

Java中线程间共享变量的问题(11)
EN

Stack Overflow用户
提问于 2020-12-26 09:59:00
回答 1查看 122关注 0票数 0

也许我希望表达的不是那么清楚,第一个例子是关于何时以及如何使用

的示例,为了使程序成功运行,我们需要添加易失性。第二种是希望表达,即使没有易失性,程序也会成功运行。我希望知道为什么在没有“不稳定”的情况下会发生这种情况

在第一个示例中,使用易失性的典型示例

代码语言:javascript
复制
public static int num=1;

public static class MyThread extends Thread {
    // flag
    private boolean flag = false ;
    public boolean isFlag() { return flag;}
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) { e.printStackTrace();
        }
// change flag to true
        this.flag = true ;
        System.out.println("flag=" + flag);
        this.flag=true;
    }
}
// main
static void testWithOutVolatile(){
    MyThread t=new MyThread();
    t.start();
    while(true) {
        boolean is=t.flag;
        if (is) {
            System.out.println("run======");
        }
    }
}

启动后,主线程将找不到更改标志,除非使用易失性。

然而,在示例中,thread2意外地得到了标志的更改,为什么会发生这种情况?

代码语言:javascript
复制
static int amb=0;
static void testSimple(){
    Thread t1=new Thread(()->{
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        amb++;
    });
    Thread t2=new Thread(()->{while(true) {
        if (amb == 0) {
            System.out.println("no");
        }
        if (amb != 0) {
            System.out.println("SUc");
            break;
        }
    }});
    t2.start();
    t1.start();
}

经过一次尝试,我发现如果我删除代码

代码语言:javascript
复制
if (amb == 0) {
            System.out.println("no");
        }

它会像我想的那样运行,thread2无法得到更改。

谢谢你的回答,QwQ

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-26 10:36:11

在第二种情况下,io语句可能刷新线程的缓冲区

代码语言:javascript
复制
Thread t2=new Thread(()->{while(true) {
        System.out.println("no");
        if (amb != 0) {
            System.out.println("SUc");
            break;
        }
    }});

如果我使用io语句(Sout),它将成功地工作。

通过这种方式,我不断地在println中找到理由,我也找到了真正的原因。

代码语言:javascript
复制
 public void println(String x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

同步导致线程切换

通过开关,线程的缓冲区是透明的,

所以thread2读取了一个新的值

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65455228

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档