1、JMM模型
Java內存模型 JMM
就是爲了解決多線程場景下併發問題的一個重要規範
CPU 和緩存的一致性問題
CPU 執行應用程序 SparkApp,僅僅只負責執行
Data:在計算的物理內存裏面
他們是處在不同的地方,隨着技術的發展,CPU的速度是大於內存的
高速的CPU去內存讀和寫,內存肯定是跟不上的
所以在CPU 和物理內存 之間有個 高速緩存
一級緩存
二級緩存
三級緩存
2、高併發三原則
併發編程三原則:
1、原子性 一個操作再CPU當中,不可以中斷,要麼全部過程執行完,要麼失敗
2、可見性 A線程改變的值,B線程是可以看到的
3、有序性 代碼編譯之後的重排,有先後順序執行
可見性:volatile,但不保證原子性
多個線程對主內存的共享變量的操作是可見的
原子性:要麼同時成功,要麼同時失敗
先編譯下class文件,查看字節碼
藉助於JUC下面的 Atomic 來解決
package com.ruozedata.jvm;
import java.util.concurrent.atomic.AtomicInteger;
public class JMMDemo {
public static void main(String[] args) {
final Data data=new Data();
//這段代碼 測試可見性
// new Thread(new Runnable() {
// public void run() {
// System.out.println(Thread.currentThread().getName());
// try {
// Thread.sleep(2000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// data.updateNumber();
// System.out.println(Thread.currentThread().getName()+" number= "+data.number);
// }
// },"JMMDemo").start();
//
// //第二個線程
// while (data.number==0){
//
// }
// System.out.println(Thread.currentThread().getName()+" number= "+data.number);
// 這段代碼測試 原子性
for (int i=0;i<10;i++){
new Thread(new Runnable() {
public void run() {
for (int j=0;j<10000;j++){
data.increment();
data.incrementAtomic();
}
}
},"JMMDemo"+i).start();
}
while (Thread.activeCount()>2){
Thread.yield();
}
System.out.println(Thread.currentThread().getName()+" number= "+data.number);
System.out.println(Thread.currentThread().getName()+" number= "+data.integer.get());
}
}
class Data{
volatile int number=0; //volatile 如果沒有加這個關鍵字,第二個線程 都沒有執行
public void updateNumber(){
this.number=100;
}
public void increment(){ //synchronized也可以保證原子性
number++;
}
AtomicInteger integer=new AtomicInteger(); // 藉助 JUC下面的 Atomic 來解決
public void incrementAtomic(){
integer.getAndIncrement();
}
}