volatile与System.out不得不说的爱恨纠葛之第三者synchronized

既然你点进来了,那就证明你知道volatile的作用是线程共享。

那么请见下面例子:

public class Warehouse extends Thread{
    boolean flag = true;

    @Override
    public void run() {
        while (true) {
            if (!flag) {
                break;
            } else {
                System.out.println(flag);
            }
        }
    }


    public static void main(String[] args) throws InterruptedException {
        Warehouse warehouse = new Warehouse();
        warehouse.start();
        Thread.sleep(1000);
        warehouse.flag=false;

    }
}

请问线程是否会终止?

答案是会,这里有人可能会感到奇怪,问什么?我也是困惑了好久,感觉这并不符合逻辑啊。后来发现原来是因为System.out.println搞的鬼,我们注释掉这句代码就可以实现效果。我们来看一下System.out.println他的源代码就明确了。

    public void println(boolean x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
    public void print(boolean b) {
        write(b ? "true" : "false");
    }
    private void write(String s) {
        try {
            synchronized (this) {
                ensureOpen();
                textOut.write(s);
                textOut.flushBuffer();
                charOut.flushBuffer();
                if (autoFlush && (s.indexOf('\n') >= 0))
                    out.flush();
            }
        }
        catch (InterruptedIOException x) {
            Thread.currentThread().interrupt();
        }
        catch (IOException x) {
            trouble = true;
        }
    }

JMM关于synchronized的两条规定:

  1)线程解锁前,必须把共享变量的最新值刷新到主内存中

  2)线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新获取最新的值

   (注意:加锁与解锁需要是同一把锁)

     通过以上两点,可以看到synchronized能够实现可见性。同时,由于synchronized具有同步锁,所以它也具有原子性

所以使用了synchronized就已经保证了数据的可见性。这个坑货,忽然想到这可以作为一道面试题23333333。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值