volatile可见性是什么?是如何实现的?

XIAO 2020-04-18 22:13:31 java常见问答 5967

对java软件开发有一定了解的小伙伴,那么对其相关的关键字应该也不陌生,volatile一定是配拥有名字的关键字,下面就跟小编一起来看看volatile的可见性是指什么,以及volatile是如何实现的?

其实可见性就是,在多线程环境中,对共享变量的修改对于其他线程是否立即可见的问题。例如:

子线程,1s之后,将flag修改为true;

public class TestVolatile extends Thread
{
    boolean flag = false;
    @Override
    public void run()
    {
        try
        {
            Thread.sleep(1000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        flag = true;
        System.out.println("flag:" + isFlag());
    }
    public boolean isFlag()
    {
        return flag;
    }
}

主线程,不断判断flag的值,如果被修改,则打印并终止;

public class Main
{
    public static void main(String[] args) throws InterruptedException
    {
        TestVolatile thread = new TestVolatile();
        thread.start();
        while (true)
        {
            if (thread.isFlag())
            {
                System.out.println("flag被改了");
                break;
            }
        }
    }
}

如果说一切正常的话,1s后,主线程将会打印"flag被改了",但是其实真实情况确是子线程真的把flag改了,但是主线程一直没有感知到flag的变化,进入了死循环。这就是没有满足可见性所带来的问题。

至于为什么volatile能保证可见性,我们可以从其规则可窥一二:修改了volatile变量,就必须立即同步到主存,同时可以使其他线程工作内存中的值变为无效;在使用volatile变量前,必须先从主存刷新,以此来保证其可见性

同样以上面的代码为例:子线程将flag修改为true,同步到主存,同时使主线程的工作内存中的flag失效,主线程下次使用flag时if (thread.isFlag()),发现工作内存中的flag已经失效,而且由于volatile的影响,在使用flag前本来也会强制从主存刷新,将会得到最新的值true。可以看得出来volatile对于单纯的set/get场景是非常好用的。

那么以上就是有关volatile可见性的所有内容了,如果还想了解更多java一些知识问答,记得关注本站消息哦。