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();
} } }

最新文章

  1. 【Spring】浅析Spring框架的搭建
  2. 【Lamp】 Linux 下安装PHP+Apache+Mysql 手记
  3. Karma 4 - Karma 集成 Webpack 进行单元测试
  4. Webpack使用教程三(webpack-dev-server)
  5. 如何借助于UML完成我们对系统的设计?谈谈我的理解
  6. YII中的session和cookie
  7. show drop down menu within/from action bar
  8. SQL点滴18—SqlServer中的merge操作,相当地风骚
  9. 2015年ACM长春区域赛比赛感悟
  10. angular指令中@,=,&的区别
  11. android EditText设置
  12. paping使用来测试联通&amp;网站由于tcp协议导致的无法通信问题超时问题
  13. 由于服务主机:DCOM服务进程占用过多CPU,导致系统卡死
  14. ADT打开layout目录的xml报错java.lang.NullPointerException
  15. git 小乌龟安装教程
  16. Echarts官网展示
  17. LeetCode 20. 有效的括号( 括号配对 )
  18. Qt5.9一个简单的多线程实例(类QThread)(第一种方法)
  19. Gradle详细解析***
  20. webpack 打包调试

热门文章

  1. 关于Jmeter线程数Ramp-Up.循环次数的理解和实验数据
  2. 字节一面:事务还没提交的时候,redolog 能不能被持久化到磁盘呢?
  3. 611. Valid Triangle Number
  4. golang中的反射reflect详解
  5. 第03讲:Flink 的编程模型与其他框架比较
  6. 学习Java第4天
  7. JavaBeginnersTutorial 中文系列教程&#183;翻译完成
  8. JVM常用命令(九)
  9. 简单说说ES6新特性
  10. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 解决