并发和多线程(七)--volatile
volatile:
相当于轻量级的synchronized,因为不存在线程上下文切换这种消耗很大的操作,volatile的读写都是无锁的操作,但是应用范围相对较少,volatile一般用来修饰变量。
volatile不能保证原子性:
在之前的博客有说到,通过Atomic相关类、synchronized、lock等都能够实现原子性,也就是共享变量的访问互斥,但是volatile无法保证原子性。volatile符合happens-before原则,所以具有可见性和有序性。
volatile保证可见性:
1、通过加入内存屏障来实现
2、对volatile变量进行读写操作,都会通过store、load来强制从主存中读取最新的值,或将数据强制刷新到主存中。
volatile保证有序性:
通过禁止指令重排保证有序性。
volatile使用场景:
1.不适合计数场景:因为无法保证原子性。
3.适合作为状态标示量:例如多线程下作为boolean类型的flag,但是必须只是单纯被多个线程赋值,不能包含其他的操作,如flag = true;如果依赖之前的结果,这样同样不是线程安全,如flag = !flag。
3.作为触发器:volatile修饰的变量放在后面,之前的所有操作都是具有可见性的,然后变量作为条件判断,实现触发器的作用。
4.doubleCheck:
单例doubleCheck实现:
- public class SingletonExample {
- // 私有构造函数
- private SingletonExample() {
- }
- //分配内存一共有三步
- // 1、memory = allocate() 分配对象的内存空间
- // 2、ctorInstance() 初始化对象
- // 3、instance = memory 设置instance指向刚分配的内存
- // 单例对象 volatile + 双重检测机制 -> 禁止指令重排
- private volatile static SingletonExample instance = null;
- // 静态的工厂方法
- public static SingletonExample getInstance() {
- if (instance == null) { // 双重检测机制
- synchronized (SingletonExample.class) { // 同步锁
- if (instance == null) {
- instance = new SingletonExample();
- }
- }
- }
- return instance;
- }
- }
并发和多线程(七)--volatile的更多相关文章
- 并发和多线程-八面玲珑的synchronized
上篇<并发和多线程-说说面试常考平时少用的volatile>主要介绍的是volatile的可见性.原子性等特性,同时也通过一些实例简单与synchronized做了对比. 相比较volat ...
- Java并发和多线程:序
近期,和不少公司的"大牛"聊了聊,当中非常多是关于"并发和多线程"."系统架构"."分布式"等方面内容的.不少问题, ...
- Java并发编程之三:volatile关键字解析 转载
目录: <Java并发编程之三:volatile关键字解析 转载> <Synchronized之一:基本使用> volatile这个关键字可能很多朋友都听说过,或许也都用过 ...
- python并发编程&多线程(二)
前导理论知识见:python并发编程&多线程(一) 一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性 官网链 ...
- python并发编程&多线程(一)
本篇理论居多,实际操作见: python并发编程&多线程(二) 一 什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一 ...
- Java并发编程知识点总结Volatile、Synchronized、Lock实现原理
Volatile关键字及其实现原理 在多线程并发编程中,Volatile可以理解为轻量级的Synchronized,用volatile关键字声明的变量,叫做共享变量,其保证了变量的“可见性”以及“有序 ...
- 7.并发编程--多线程通信-wait-notify
并发编程--多线程通信-wait-notify 多线程通信:线程通信的目的是为了能够让线程之间相互发送信号; 1. 多线程通信: 线程通信的目的是为了能够让线程之间相互发送信号.另外,线程通信还能够使 ...
- Java并发与多线程与锁优化
前言 目前CPU的运算速度已经达到了百亿次每秒,所以为了提高生产率和高效地完成任务,基本上都采用多线程和并发的运作方式. 并发(Concurrency):是指在某个时间段内,多任务交替处理的能力.CP ...
- 并发和多线程(二)--启动和中断线程(Interrupt)的正确姿势
启动线程: 从一个最基本的面试题开始,启动线程到底是start()还是run()? Runnable runnable = () -> System.out.println(Thread.cur ...
随机推荐
- MySQL-PREPARE语句
MySQL-PREPARE语句 功能介绍: MySQL准备语句用法 为了使用MySQL准备语句,您需要使用其他三个MySQL语句如下: PREPARE - 准备执行的声明. EXECUTE - 执行由 ...
- 展开阅读全文 js 爬虫操作
from selenium import webdriver import time import random from bs4 import * browser = webdriver.Chrom ...
- SQLyog普通版与SQLyog企业版对比分析
这里,为什么要写这篇博客呢? 对于SQLyog普通版而言,只能复制到不同的数据库里,这样显得麻烦,当然,你也可以用语句来操作达到实现目的. 具体做法: MySQL复制旧表的结构及数据到新表 CREAT ...
- SemaphoreSlim
https://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim(v=vs.110).aspx Represents a ...
- eclipse导出签名apk的混淆设置
1.设置project.properties文件: 2.设置proguard-project.txt文件:
- 洛谷 P1970 花匠 —— DP
题目:https://www.luogu.org/problemnew/show/P1970 普通的DP,f[i][0/1] 表示 i 处处于较小或较大的长度: 注意:1.树状数组向后 query 时 ...
- git服务器的建立
git简介 首先,与以前广为流行的SVN不同,git是分布式的,其没有服务器端与客户端之分(虽然在项目管理过程中,一般会人为地指定某一台非开发用的机器作为“服务器”,但就git自身功能来说,完全可以没 ...
- Liunx中虚拟机远程复制文件SCP命令
1.首先在虚拟机中新建 CentOSA .CentOSB 从远处复制文件到本地目录 scp -r root@192.168.1.24:/root/aa ./ 从CentosB虚拟机器上的/root/a ...
- Redis集群创建和配置
1.检查GCC是否安装,可以看看版本号 gcc -v 安装命令:yum install gcc-c++ 2.安装Ruby和Rubygems 如果有网的话,则通过yum命令进行安装,自动将关联的依赖包全 ...
- 对路径 obj 文件夹访问被拒绝
TFS 刚下载的项目,出现该问题. 解决方案: 将文件夹属性“只读”,取消