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关键字的相关学习记录的更多相关文章

  1. Java并发编程:volatile关键字解析(学习总结-海子)

    博文地址:Java并发编程:volatile关键字解析

  2. Yii2的相关学习记录,前后台分离及migrate使用(七)

    最近一直忙其它的(其实是懒!),将<深入理解Yii2>看了一遍,一些当初没明白的稍微明了了点,然后又看yii2的图片上传等处理.富文本.restful什么的,但由于没进行到这里,只看也不管 ...

  3. Yii2的相关学习记录,下载Yii2(一)

    原先学习过Yii1的相关知识,虽然也是半懂不懂的,但稍微的结构是了解的.现在利用晚上的时间学习下Yii2的使用,打算建一个后台管理系统,这里记录下,以免自己以后忘记. 目前已看一部分Yii2的权威指南 ...

  4. java 项目相关 学习记录

    一位资深程序员大牛给予Java初学者的学习路线建议  [任何时期都可以好好看看] https://www.imooc.com/article/8993 https://www.jianshu.com/ ...

  5. Yii2的相关学习记录,alert等美化、confirm异步、session中的flash及小部件的使用(六)

    呃,系统自带的alert.confirm等弹出框实在是难看,作为一个颜控,这能忍? 这里我用的是kartik-v/yii2-dialog,这个是基于bootstrap3-dialog这个来做了一些常用 ...

  6. Yii2的相关学习记录,初始化Yii2(二)

    前面已经将Yii2下载下来了,那我们就需要能实际的使用. 一.初始化,因为我都是在windows系统下,所以用cmd命令打开下载下来的Yii2的根目录.然后运行下面命令: init 会提示选择0为开发 ...

  7. linux 相关学习记录

    (一)概念① 物理CPU实际Server中插槽上的CPU个数物理cpu数量,可以数不重复的 physical id 有几个② 逻辑CPU /proc/cpuinfo 用来存储cpu硬件信息的信息内容分 ...

  8. 使用hibernate更新数据库记录的信息的相关学习记录

    截选代码(可能遗漏标点符号): package name.sql; import java.util.List; import name.session.HibernateSessionFactory ...

  9. Fiddler使用 断点 模拟返回 AutoResponder Mock 模拟数据 相关学习记录

    断点 测试中有时需要改变发出去的请求信息,需要用到打断点的方法.断点包含两种方式: before response:在request请求的时候,未到达服务器之前,一般用来修改请求参数 after re ...

随机推荐

  1. conda : 无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称

    conda : 无法将"conda"项识别为 cmdlet.函数.脚本文件或可运行程序的名称.请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次. 解决办法: 没有添加系 ...

  2. 【解决了一个小问题】golang中引用一个路径较长的库,导致goland中出现"module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2"

    在项目中的go.mod文件中有这样一句: require ( github.com/xxx-devops/xx1/sdk/go v2.2.3 ) 项目的编译没有问题,但是goland中出现如下提示: ...

  3. 0,NULL和nullpter

    #include <iostream> using namespace std; void f(int) { cout<<"f(int)"<<e ...

  4. C++构造函数语义学(三)(基于C++对象模型)

    带有虚基类的情况. 1 #include<iostream> 2 using namespace std; 3 class X 4 { 5 public: 6 int i; 7 }; 8 ...

  5. python浮点数计算--5

    #!/usr/bin/python #coding=utf-8 i=1.0 j=3 print(i*j) print(i+j) print(i**j) 备注:无论是哪种运算,只要有操作数是浮点数,py ...

  6. ORA-15081: failed to submit an I/O operation to a disk

    Problem: While restoring controlfile to test environment, from filesystem or tape environment after ...

  7. 学习JAVAWEB第八天

    1. C/S:客户端/服务器端 2. B/S:浏览器/服务器端 2. 资源分类 1. 静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源.静态资源可以直接被浏览器解析 * 如: html,c ...

  8. Linux 配置 SVN and ideal 配置SVN的客户端 ?

    Linux 配置 SVN? 4.配置svn(服务器端) 项目管理工具(subversion),每个公司都会用到(git/svn) 目的就是为了合作开发 4.1.从linux上安装svn 不需要从官网下 ...

  9. Ubuntu安装盘的制作

    准备工作 Ubuntu系统镜像 win32diskimager U盘(4G以上),对重要文件提前备份 制作 下载系统镜像 进入官网 我们下载的版本是18.04,不是20.04 在页面中,找到BitTo ...

  10. iBooker AI+财务提升星球 2020.4 热门讨论

    比特币量化套利的心路历程(附python量化招聘)(分享自知- 如何选择一份好的工作? 你知道为什么大家都想去好公司吗? 不- #财务知识# 可转债套利 辉丰转债128012套利之三个知道- #财务知 ...