java并发编程(十五)内存可见两种方式 加锁和volatile

1、volatile变量是一种稍弱的同步机制在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比synchronized关键字更轻量级的同步机制。

2、从内存可见性的角度看,写入volatile变量相当于退出同步代码块,而读取volatile变量相当于进入同步代码块。

3、在代码中如果过度依赖volatile变量来控制状态的可见性,通常会比使用锁的代码更脆弱,也更难以理解。仅当volatile变量能简化代码的实现以及对同步策略的验证时,才应该使用它。一般来说,用同步机制会更安全些。

4、加锁机制(即同步机制)既可以确保可见性又可以确保原子性,而volatile变量只能确保可见性,原因是声明为volatile的简单变量如果当前值与该变量以前的值相关,那么volatile关键字不起作用,也就是说如下的表达式都不是原子操作:“count++”、“count = count+1”。

当且仅当满足以下所有条件时,才应该使用volatile变量:

1、对变量的写入操作不依赖变量的当前值,或者你能确保只有单个线程更新变量的值。

2、该变量没有包含在具有其他变量的不变式中。

总结:在需要同步的时候,第一选择应该是synchronized关键字,这是最安全的方式,尝试其他任何方式都是有风险的。尤其在、jdK1.5之后,对synchronized同步机制做了很多优化,如:自适应的自旋锁、锁粗化、锁消除、轻量级锁等,使得它的性能明显有了很大的提升。

时间: 2024-12-28 21:29:52

java并发编程(十五)内存可见两种方式 加锁和volatile的相关文章

7 并发编程-(线程)-开启线程的两种方式

thread/英 /θred/ 美 /θr?d/  线程 1.threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 2.开启线程的两种方式 2.1.方式一 from threading import Thread import time def task(name): print(f"{name} is running") time.sleep(2) print(f"{name} i

内存分配原理 -进程分配内存的两种方式,分别有系统调用完成brk() 和mmap()(不设计共享内存)

如何查看进程发生缺页中断的次数? 用ps -o majflt,minflt -C program命令查看. majflt代表major fault,中文名叫大错误,minflt代表minor fault,中文名叫小错误.           这两个数值表示一个进程自启动以来所发生的缺页中断的次数. 发成缺页中断后,执行了那些操作? 当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作: 1.检查要访问的虚拟地址是否合法 2.查找/分配一个物理页 3.填充物理页内容(读取磁盘,或者直接置0

Java并发编程(五)ConcurrentHashMap的实现原理和源码分析

相关文章 Java并发编程(一)线程定义.状态和属性 Java并发编程(二)同步 Java并发编程(三)volatile域 Java并发编程(四)Java内存模型 前言 在Java1.5中,并发编程大师Doug Lea给我们带来了concurrent包,而该包中提供的ConcurrentHashMap是线程安全并且高效的HashMap,本节我们就来研究下ConcurrentHashMap是如何保证线程安全的同时又能高效的操作. 1.为何用ConcurrentHashMap 在并发编程中使用Has

Java接入Spark之创建RDD的两种方式和操作RDD

首先看看思维导图,我的spark是1.6.1版本,jdk是1.7版本 spark是什么? Spark是基于内存计算的大数据并行计算框架.Spark基于内存计算,提高了在大数据环境下数据处理的实时性,同时保证了高容错性和高可伸缩性,允许用户将Spark 部署在大量廉价硬件之上,形成集群. 下载和安装 可以看我之前发表的博客 Spark安装 安装成功后运行示例程序 在spark安装目录下examples/src/main目录中. 运行的一个Java或Scala示例程序,使用bin/run-examp

【并发编程】实现多线程的几种方式

摘自:https://www.cnblogs.com/54chensongxia/p/11970827.html 本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 在Java中有多种方式可以实现多线程编程(记得这是一道常问的面试题,特别是在应届生找工作的时候被问的频率就更高了). 继承Thread类并重写run方法: 实现Runnable接口,并将这个类的实例当做一个target构造Thread类 实现

Android实战简易教程-第四十九枪(两种方式实现网络图片异步加载)

加载图片属于比较耗时的工作,我们需要异步进行加载,异步加载有两种方式:1.通过AsyncTask类进行:2.通过Handler来实现,下面我们就来看一下如何通过这两种方式实现网络图片的异步加载. 一.AsyncTask方式 1.main.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.co

java中读取配置文件ResourceBundle和Properties两种方式比较

今天在开发的时候,需要把一些信息放到配置文件中,方便后续的修改,注意到用的是ResourceBundle读取配置文件的方式,记得之前也见过使用Properties的方式,就比较好奇这两种方式的区别,网上查了一下和查了一下Java API手册,简单总结记录一下: ResourceBundle和Properties的一个主要区别就是ResourceBundle支持语言国际化,当程序需要特定于语言环境的对象时,它使用 getBundle 方法加载 ResourceBundle 类: Locale lo

Java线程Thread使用匿名内部类创建的两种方式

匿名内部类实现线程的两种方式: 第一种方式: 1.继承Thread类 2.重写run方法 3.将要执行的代码写在run方法中 第二种方式: 1.将Runnable的子类对象传递给Thread的构造方法 2.重写run方法 3.将执行的代码写在run方法中,最后我们开启线程 package com.yyx.thread; /** * 匿名内部类创建线程 yyx 2018年2月4日 */ public class AnonymousThread { public static void main(S

Java多线程Thread使用匿名内部类创建的两种方式

匿名内部类实现线程的两种方式: 第一种方式: 1.继承Thread类 2.重写run方法 3.将要执行的代码写在run方法中 第二种方式: 1.将Runnable的子类对象传递给Thread的构造方法 2.重写run方法 3.将执行的代码写在run方法中,最后我们开启线程 package com.yyx.thread; /** * 匿名内部类创建线程 yyx 2018年2月4日 */ public class AnonymousThread { public static void main(S