解释:
volatile是java提供的轻量级的同步机制
特点:
1.保证可见性
2.禁止指令重排
3.不保证原子性
JMM(java内存模型 线程安全的保证) https://www.jianshu.com/p/8a58d8335270
JMM同步规则:1.解锁前将数据刷回到主内存2.加锁前将主内存的数据刷到工作空间,3,加锁和解锁是同一把锁
JMM特点:1.可见性2.原子性,3,有序性
主要是主内存和工作内存(每一个线程的工作内存)
线程间的操作是通过主内存的来完成
- 寄存器:JVM内部虚拟寄存器,存取速度非常快,程序不可控制。
- 栈:保存局部变量的值:包括1.基本数据类型的值。2.保存类的实例,即堆区对象的引用(指针)。3.保存加载方法时的帧。
- 堆:用来存放动态产生的数据,比如new出来的对象。注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。因为同一个类拥有各自的成员变量,存储在堆中的不同位置,但是同一个类不同实例的他们共享该类的方法,并不是每创建一个对象就把成员方法复制一次。
- 常量池:JVM为每个加载的类型维护一个常量池,常量池是这个类型用到的常量的集合。包括直接常量(基本类型,String)和对其他类型、方法、字段的符号引用(1)。池中的数据和数组一样通过索引访问。由于常量池包含了一个类型所有的对其他类型、方法、字段的符号引用,所以常量池在Java的动态链接中起了核心作用。常量池存在于方法区中,而方法区存在于堆中。
volatile 底层实现,当添加volatile关键字后,Memory Barrier (内存屏障)第二个特点就是强制刷新出各种cpu缓存数据保证,cpu上的线程都能读到最新的数据
比较厉害的解释
https://www.cnblogs.com/jinjiyese153/p/9450832.html 应用
https://blog.csdn.net/zhjali123/article/details/80037304 优缺点 特点
- 代码实现
package volatitleDemo;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
class MyData {
volatile int number = 0;
AtomicInteger atomicInteger = new AtomicInteger(1);
//添加synchronized实现原子性
public synchronized void addNumber() {
this.number = 60;
}
public void addNumberPul(){
number++;
}
public void myAtomicAdd(){
atomicInteger.getAndIncrement();
}
}
/**
* 1.1未加volatile时可见性没有实现,无法跳出循环
* {
* AAA come in
* * AAA update number value is60
* }
* 1.2添加volatile时可见性实现,跳出循环
* 打印结果{
* AAA come in
* AAA update number value is60
* update number is ok60
* }
* 2.1volatitle 不保证原子性,不可分割完整性,
* 也就是某个线程在处理问题时其他无法加塞和被分割,也就是要保证完整性和也就是成功或者失败
如何解决:
使用juc下的AtomicInteger
*/
public class VolatitleDemo {
public static void main(String args[]) {
//seeOkByVolatitle();
MyData myData = new MyData();
for(int i = 0;i<20;i++){
new Thread(()->{
for(int j = 0;j<1000;j++){
myData.addNumberPul();
myData.myAtomicAdd();
}
},String.valueOf(i)).start();
}
//等待20个线程执行完毕,再通过main线程取得最终的结果值
while (Thread.activeCount()>2){
Thread.yield();
}
System.out.println(Thread.currentThread().getName()+"\t fianl number is"+myData.number);
System.out.println(Thread.currentThread().getName()+"atomic number is ok" + myData.atomicInteger);
}
//volatitle保证原子性,及时通知主内存的值发生了改变
public static void seeOkByVolatitle() {
MyData myData = new MyData();
Thread thread = new Thread();
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t come in");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
myData.addNumber();
System.out.println(Thread.currentThread().getName() + "\t update number value is" + myData.number);
}, "AAA").start();
while (myData.number == 0) {
//测试是否成功修改了值如果没有则一直在循环
}
System.out.println("int number is ok" + myData.number);
}
}