专栏首页java开发的那点事深度理解volatile关键字

深度理解volatile关键字

最轻量的同步机制

获取被volatile修饰的变量的时候,每次都要从主内存中获取

设置被volatile修饰的变量的时候,每次都要刷回主内存当中

当其他线程调用的时候,会将自己线程当中保存的变量值置为无效,然后重新重主内存获取

在读取和写入到主内存的时候,不会进行加锁,所以称之为最轻量的同步机制

volatile不是线程安全的,他只能保证变量的可见性,无法保证其原子性,如果设置的时候采用运算方式,那么将无法保证线程安全

运算方式

public volatile int age = 200;

set age = age+20; // 无法保证操作的原子性

这就是运算赋值(简写)

测试用例:

package org.dance.day1.vola;

import org.dance.tools.SleepTools;

/**
 * volatile无法保证操作的原子性
 * @author ZYGisComputer
 */
public class VolatileUnsafe {

    private static class VolatileVar implements Runnable{

        private volatile int a = 0;

        @Override
        public void run() {
            String name = Thread.currentThread().getName();
            a = a + 1;
            System.out.println(name + ":" + a);
            SleepTools.ms(100);
            a = a + 1;
            System.out.println(name + ":" + a);
        }
    }

    public static void main(String[] args) {
        VolatileVar volatileVar = new VolatileVar();
        Thread thread = new Thread(volatileVar);
        Thread thread1 = new Thread(volatileVar);
        Thread thread2 = new Thread(volatileVar);
        Thread thread3 = new Thread(volatileVar);
        thread.start();
        thread1.start();
        thread2.start();
        thread3.start();
    }

}

返回测试结果:

Thread-0:1
Thread-3:4
Thread-2:3
Thread-1:2
Thread-0:5
Thread-1:7
Thread-2:6
Thread-3:5

可以看见volatile无法保证操作的原子性

所以说volatile关键字适用于一个线程写,多个线程读的场景,因为他只能保证可见性,不能保证原子性

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 在请求目标中找到无效字符。有效字符在RFC 7230和RFC 3986中定义

      今天在使用Tomcat8部署完成项目做测试的时候,发现有的接口会报错400,后端提示在请求目标中找到无效字符。有效字符在RFC 7230和RFC 3986中...

    彼岸舞
  • Synchronized内置锁

    多个线程之间共享资源就会发成数据上的冲突,我们往往会使用Synchronized关键字来实现锁

    彼岸舞
  • Mysql执行计划(大章)

    使用explain关键字可以模拟优化器执行SQL查询语句,从而知道Mysql是如何处理你的SQL语句的。分析你的查询语句或者表结构的性能瓶颈

    彼岸舞
  • java安全编码指南之:Thread API调用规则

    java中多线程的开发中少不了使用Thread,我们在使用Thread中提供的API过程中,应该注意些什么规则呢?

    程序那些事
  • [javaSE] 看博客学习多线程的创建方式和优劣比较和PHP多线程

    Runnable是一个接口,定义一个类MyRunnable实现Runnable接口,实现run()方法,

    陶士涵
  • 并发基础(三): java线程优先级小试牛刀

    好好学java
  • 某团面试题:JVM 堆内存溢出后,其他线程是否可继续工作?

    这道题其实很有难度,涉及的知识点有jvm内存分配、作用域、gc等,不是简单的是与否的问题。

    良月柒
  • 某团面试题:JVM 堆内存溢出后,其他线程是否可继续工作?

    最近网上出现一个美团面试题:“一个线程OOM后,其他线程还能运行吗?”。我看网上出现了很多不靠谱的答案。这道题其实很有难度,涉及的知识点有jvm内存分配、作用域...

    乔戈里
  • 某团面试题:JVM 堆内存溢出后,其他线程是否可继续工作?

    最近网上出现一个美团面试题:“一个线程OOM后,其他线程还能运行吗?”。我看网上出现了很多不靠谱的答案。这道题其实很有难度,涉及的知识点有jvm内存分配、作用域...

    芋道源码
  • 美团面试题:JVM堆内存溢出后,其他线程是否可继续工作?

    最近网上出现一个美团面试题:“一个线程OOM后,其他线程还能运行吗?”。我看网上出现了很多不靠谱的答案。这道题其实很有难度,涉及的知识点有jvm内存分配、作用域...

    Spark学习技巧

扫码关注云+社区

领取腾讯云代金券