volatile关键字的相关学习记录
2024-09-07 22:32:17
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();
} } }
最新文章
- 【Spring】浅析Spring框架的搭建
- 【Lamp】 Linux 下安装PHP+Apache+Mysql 手记
- Karma 4 - Karma 集成 Webpack 进行单元测试
- Webpack使用教程三(webpack-dev-server)
- 如何借助于UML完成我们对系统的设计?谈谈我的理解
- YII中的session和cookie
- show drop down menu within/from action bar
- SQL点滴18—SqlServer中的merge操作,相当地风骚
- 2015年ACM长春区域赛比赛感悟
- angular指令中@,=,&的区别
- android EditText设置
- paping使用来测试联通&;网站由于tcp协议导致的无法通信问题超时问题
- 由于服务主机:DCOM服务进程占用过多CPU,导致系统卡死
- ADT打开layout目录的xml报错java.lang.NullPointerException
- git 小乌龟安装教程
- Echarts官网展示
- LeetCode 20. 有效的括号( 括号配对 )
- Qt5.9一个简单的多线程实例(类QThread)(第一种方法)
- Gradle详细解析***
- webpack 打包调试
热门文章
- 关于Jmeter线程数Ramp-Up.循环次数的理解和实验数据
- 字节一面:事务还没提交的时候,redolog 能不能被持久化到磁盘呢?
- 611. Valid Triangle Number
- golang中的反射reflect详解
- 第03讲:Flink 的编程模型与其他框架比较
- 学习Java第4天
- JavaBeginnersTutorial 中文系列教程&#183;翻译完成
- JVM常用命令(九)
- 简单说说ES6新特性
- Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 解决