volatile可见性代码验证

volatile可见性代码验证

大厂面试题:

1、请你谈谈对volatile的理解?

2、CAS你知道吗?

3、原子类AtomicInteger的ABA问题谈谈?原子更新引用知道吗?

4、我们都知道ArrayList是线程不安全的,请编码写一个不安全的案例并给出解决方案?

5、公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自旋锁。

6、CountDownLatch、CyclicBarrier、Semaphore使用过吗?

7、阻塞队列知道吗?

8、线程池用过吗?ThreadPoolExecutor谈谈你的理解?

9、线程池用过吗?生产上你是如何设置合理参数?

10、死锁编码及定位分析?

 

volatile可见性代码验证                 

Demo One:定义的变量没有被volatile修饰是没有可见性的

public class VolatileVisibleDemo {

    private int num = 0;

 

    public void addNum() {

        num = num + 60;

    }

 

    public static void main(String[] args) {

        VolatileVisibleDemo volatileVisibleDemo = new VolatileVisibleDemo();

        // t1线程对num就行更改操作

        new Thread(() -> {

            System.out.println(Thread.currentThread().getName() + "\t come in");

            try {

                // 模拟num更改操作耗时3m,并保证其他线程读取了num变量

                Thread.sleep(3000);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            volatileVisibleDemo.addNum();

            System.out.println(Thread.currentThread().getName() + "\t" + "num值已经被更改为:" + volatileVisibleDemo.num);

        }, "t1").start();

 

        while (volatileVisibleDemo.num == 0) {

            // main线程一直等待,直到num不等于0

        }

        System.out.println(Thread.currentThread().getName() + "\t mission is over");

    }

}          

程序会一直卡在while循环那里,因为线程之间不可见,main线程永远拿不到子线程t1更改后的值。

Demo Two:定义的变量被volatile修饰是可见的

public class VolatileVisibleTwoDemo {

       // 被volatile修饰的变量,线程间是可见的

    private volatile int num = 0;

 

    public void addNum() {

        num = num + 60;

    }

 

    public static void main(String[] args) {

        VolatileVisibleTwoDemo volatileVisibleDemo = new VolatileVisibleTwoDemo();

        // t1线程对num就行更改操作

        new Thread(() -> {

            System.out.println(Thread.currentThread().getName() + "\t come in");

            try {

                // 模拟num更改操作耗时3m,并保证其他线程读取了num变量

                Thread.sleep(3000);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

                     // 当t1线程更改num之后,t1线程会把更新后的num值写回主内存空间,并通知main线程重新去主内存空间获取最新的副本变量。

            volatileVisibleDemo.addNum();

            System.out.println(Thread.currentThread().getName() + "\t" + "num值已经被更改为:" + volatileVisibleDemo.num);

        }, "t1").start();

 

        while (volatileVisibleDemo.num == 0) {

            // main线程一直等待,直到num不等于0

        }

        System.out.println(Thread.currentThread().getName() + "\t mission is over");

    }

}                     

 

程序执行结果如下:

 

如果此时你已经把volatile可见性原理分析很清楚,接下来面试官可能会问你:

volatile为什么不保证原子性?

请你使用代码验证下volatile不保证原子性?

有什么办法让volatile保证原子性?

参考答案请看下一小节:volatile不保证原子性

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值