可见性:
一个线程在对一个变量进行操作时,其他线程对这个变量是可见的。 线程是可以并行的
简单来说:线程一操作i变量进行加减写入主内存,其他线程操作该变量时,使工作内存的变量失效,再从主内存重新获取变量进行操作。
比较典型例子:JMM模型底层采用的时MESI协议的嗅探机制进行处理,volatile也是这种原理
唯一的缺点是:不能解决原子性,导致下面问题出现,出现俩个1。
原因是多个线程同时写入主内存,得到一样的返回结果
package com.zking.lock;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @description:
* @author: codinglife
* @time: 2021/3/11 16:56
*/
public class Mylock implements Runnable {
private static CountDownLatch countDownLatch=new CountDownLatch(10);
//static AtomicInteger atomicInteger=new AtomicInteger(0);
static volatile int i=0;
//自增数
public static Integer create(){
// return atomicInteger.incrementAndGet();
return i++;
}
@Override
public void run() {
try {
//先阻塞
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(create()+"-----"+Thread.currentThread().getId());
}
public static void invoke(){
for(int i=0;i<10;i++){ //循环10次
// System.out.println(create());
new Thread(new Mylock()).start();
countDownLatch.countDown(); //countDownLatch 减一 //到0时唤醒线程
}
}
public static void main(String[] args) {
invoke();
}
}
原子性:一个线程在对一个变量进行操作时,其他线程对该变量无法操作 他是同步的。
上述问题就是多个线程对变量进行同时操作,导致结果不准确
但是原子性并不能保证可见性,例如:CAS(比较与交换),保证了原子性,
它是保证compare-set的整体性,但是如果对同一个变量,同一块主内存无法保证可见性的话,就无法从主内存重新获取其他线程修改的数据,那么compare就没有意义了,同时这也是一种并发的情况
所以多线程对于同一变量进行CAS操作时,应该要保证变量的可见性,例如:Atomic。