volatile关键字的相关学习记录
1:volatile是什么?
Volatile是java虚拟机提供的一种轻量级的同步机制,具有 三大特性,分别是:保证可见性、不保证原子性、禁止指令重排
可见性:
概念:每一个线程都有自己的工作内存,线程不能直接操作主内存的值,必须把主内存的数据拷贝回工作内存进行更改后,刷新回主内存,并及时通知其他线程
import java.util.concurrent.TimeUnit;
public class test {
    public static void main(String[] args) {
        MyData myData = new MyData();
        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
            }catch (Exception e){
            }
            myData.addTo60();
            System.out.println(Thread.currentThread().getName() + " update value to 60 :" + myData.number);
        },"AAA").start();
        while (myData.number == 0){
        }
        System.out.println(Thread.currentThread().getName() + " get value mydata.number :" + myData.number);
    }
}
class MyData{
    /**
     * 当加了volatile这个关键字的时候,由于其中一个线程修改完毕 立即通知,那么另一个线程就会收到值被修改,则在上述循环方法中将会跳出 并结束
     *
     * 如果不加,则其中一个线程将不会收到值被修改的情况,导致while循环将一直存在
     */
    volatile int number=0;
    public void addTo60(){
        this.number=60;
    }
}
不保证原子性:
代码:
import java.util.concurrent.TimeUnit;
public class test {
    public static void main(String[] args) {
        //验证volatile不保证原子性的问题
        MyData myData = new MyData();
        for (int i = 1; i <= 20; i++) {
            new Thread(()->{
                for (int j = 1; j <= 1000; j++) {
                    myData.addPlusPlus();
                }
            },String.valueOf(i)).start();
        }
        //等待执行完成,
        while (Thread.activeCount()> 2){
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + " number:" + myData.number);
    }
}
class MyData{
    volatile int number=0;
    public void addPlusPlus(){
        this.number++;
    }
}
打印结果将不可预测
处理非原子性问题
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; public class test {
public static void main(String[] args) {
//验证volate不保证原子性的问题
MyData myData = new MyData();
for (int i = 1; i <= 20; i++) {
new Thread(()->{
for (int j = 1; j <= 1000; j++) {
myData.addPlusPlus();
myData.addAtomic();
} },String.valueOf(i)).start();
} //等待执行完成,
while (Thread.activeCount()> 2){
Thread.yield();
}
System.out.println(Thread.currentThread().getName() + " number:" + myData.number);
System.out.println(Thread.currentThread().getName() + " atomic:" + myData.atomicInteger); }
} class MyData{ int number=0; public void addPlusPlus(){
number++; } AtomicInteger atomicInteger = new AtomicInteger();
public void addAtomic(){
atomicInteger.getAndIncrement(); }
}
禁止指令重排:
编译器和操作系统会对指令进行优化和重排序,通过volatile可以禁止重排序,主要是在多线程环境下,变量的顺序可能发生变化 从而导致结果不可预测的问题。
代码:单例模式使用volatile方法
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; public class test { //双端检索 + volatile 禁止指令重排序
private static volatile test t = null;
private test(){
System.out.println(Thread.currentThread().getName() + " test-构造方法!");
}
private static test getTestInstince(){
if(t == null){
synchronized (test.class){
if(t == null){
t = new test(); }
}
}
return t;
} public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(test.getTestInstince());
},Thread.currentThread().getName() + String.valueOf(i)).start();
} } }
volatile关键字的相关学习记录的更多相关文章
- Java并发编程:volatile关键字解析(学习总结-海子)
		博文地址:Java并发编程:volatile关键字解析 
- Yii2的相关学习记录,前后台分离及migrate使用(七)
		最近一直忙其它的(其实是懒!),将<深入理解Yii2>看了一遍,一些当初没明白的稍微明了了点,然后又看yii2的图片上传等处理.富文本.restful什么的,但由于没进行到这里,只看也不管 ... 
- Yii2的相关学习记录,下载Yii2(一)
		原先学习过Yii1的相关知识,虽然也是半懂不懂的,但稍微的结构是了解的.现在利用晚上的时间学习下Yii2的使用,打算建一个后台管理系统,这里记录下,以免自己以后忘记. 目前已看一部分Yii2的权威指南 ... 
- java 项目相关 学习记录
		一位资深程序员大牛给予Java初学者的学习路线建议 [任何时期都可以好好看看] https://www.imooc.com/article/8993 https://www.jianshu.com/ ... 
- Yii2的相关学习记录,alert等美化、confirm异步、session中的flash及小部件的使用(六)
		呃,系统自带的alert.confirm等弹出框实在是难看,作为一个颜控,这能忍? 这里我用的是kartik-v/yii2-dialog,这个是基于bootstrap3-dialog这个来做了一些常用 ... 
- Yii2的相关学习记录,初始化Yii2(二)
		前面已经将Yii2下载下来了,那我们就需要能实际的使用. 一.初始化,因为我都是在windows系统下,所以用cmd命令打开下载下来的Yii2的根目录.然后运行下面命令: init 会提示选择0为开发 ... 
- linux 相关学习记录
		(一)概念① 物理CPU实际Server中插槽上的CPU个数物理cpu数量,可以数不重复的 physical id 有几个② 逻辑CPU /proc/cpuinfo 用来存储cpu硬件信息的信息内容分 ... 
- 使用hibernate更新数据库记录的信息的相关学习记录
		截选代码(可能遗漏标点符号): package name.sql; import java.util.List; import name.session.HibernateSessionFactory ... 
- Fiddler使用 断点 模拟返回 AutoResponder  Mock 模拟数据 相关学习记录
		断点 测试中有时需要改变发出去的请求信息,需要用到打断点的方法.断点包含两种方式: before response:在request请求的时候,未到达服务器之前,一般用来修改请求参数 after re ... 
随机推荐
- 【Java常用类】两个Date类
			两个Date类 java.util.Date类 两个构造器的使用 构造器一:Date():创建一个对应当前时间的Date对象 构造器二:创建指定毫秒数的Date对象 两个方法的使用 toString( ... 
- LR12解决不能打开webTours服务问题
			启动the webtours apache server时提示:设置使用服务器IP地址相关信息. 解决办法: 找到LR安装目录,如:D:\LoadRunner\WebTours\conf 找到http ... 
- python分支结构与循环结构
			python分支结构 一.if 单条件形式 # 年轻人的世界都不容易 age > 18 age = int(input("请输入您的年龄:")) # input()函数 模拟 ... 
- WEB开发的相关知识(Tomcat)
			Internet上供外界访问的Web资源分为 静态web资源(如html 页面):指web页面中供人们浏览的数据始终是不变. 动态web资源:指web页面中供人们浏览的数据是由程序产生的,不同时间点访 ... 
- jmeter和JDK安装教程(Windows)
			1.JDK的安装及环境变量配置 1.JDK的下载安装 JDK官网下载地址:https://www.oracle.com/java/technologies/downloads 然后注册账号,开始下载, ... 
- Solon 开发,三、构建一个Bean的三种方式
			Solon 开发 一.注入或手动获取配置 二.注入或手动获取Bean 三.构建一个Bean的三种方式 四.Bean 扫描的三种方式 五.切面与环绕拦截 六.提取Bean的函数进行定制开发 七.自定义注 ... 
- Python向mysql数据库插入数据
			一.向表tcolor中插入数据的主要流程如下: import datetimeimport pymysql.cursorsconnection = pymysql.connect(host='loca ... 
- Windows 10 Version 21h1安装
			好久没安装过Windows 10系统了,这两天在下载电脑管家时,使用bing搜索,没注意就选择了第一个,安装后,噩梦就来了,非法广告.各种软件的推送,怎么也清不干净. 没办法,到PCBeta下载了最新 ... 
- Redis学习笔记(二)redis 底层数据结构
			在上一节提到的图中,我们知道,可以通过 redisObject 对象的 type 和 encoding 属性.可以决定Redis 主要的底层数据结构:SDS.QuickList.ZipList.Has ... 
- VsCode配置C/C++开发环境
			Visual Studio Code(VS Code)是基于 Electron 开发,支持 Windows.Linux 和 macOS 操作系统.内置了对JavaScript,TypeScript和N ... 
