因为多线程,我怼了一个同事

背景:

今天同事在看我写锁同步的总结,兴致来了想考考我,问我synchronized 保证变量的可见性吗?

我回答可以,他的答案是synchronized不保证可见性,volatile才保证可见性。结果两人起来争执,为此他特意写了如下代码来证明他说的是正确的:

重点戏

/**
 * 证明,synchronized能不能保重对象可见性。
 */
public class SynchronizedLock {

    private static int count = 0;

    public void incr() {
        synchronized (this) {
            count ++;
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizedLock synchronizedLock = new SynchronizedLock();
        for (int i = 0; i < 1000; i++) {
            new Thread(synchronizedLock::incr).start();
        }

        Thread.sleep(1000);

        System.out.println(count);
    }

}

他执行了下,他说明了之前看视频老师就是用这个实例,为什么有的时候,输出是:

999

有的时候是:

998

有的时候是:

1000

看到上面的代码,一开始我还真疑惑了一下。结果发现一个Thread.sleep(1000),这是个什么鬼,确定是最后两个线程/一个线程在println的时候已经执行了?其实确定不了,我让他把 Thread.sleep(1000); 改成 Thread.sleep(3000) ,看看打印的有998/999过吗?结果肯定是没出现过998/999。

当时就怼他的JMM基础不扎实,就只是会被网上的答案。

结论

JMM需要解决的问题就是Java多线程通信的问题,多线程通信的问题主要是三个问题:有序性、可见性和原子性。synchronized属于锁,锁也是需要解决通信的三个问题的。其中可见性是有锁的内存原语保证的:

1)获取锁的内存语义:当线程获取锁的时候,JMM会把线程对于的本地内存置为无效,从而使得被监视器保护的临界区代码必须从主内存读取共享变量。

2)释放锁的内存语义:当线程释放锁的时候,JMM会把该线程对应的本地内存中的共享变量刷新到内存中。

希望那个同事能看到这篇文章吧,他到现在都不理我了。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值