/*
對於volatile修飾的變量,jvm虛擬機只是保證從 主內存 加載到 線程工做內存的值 是最新的《直接讀取 主內存數據, 並寫回到 主內存中。中間有可能不是原子操做》
例如假如線程1,線程2 在進行read,load 操做中,發現主內存中count的值都是5,那麼都會加載這個最新的值
在線程1堆count進行修改以後,會write到主內存中,主內存中的count變量就會變爲6
線程2因爲已經進行read,load操做,在進行運算以後,也會更新主內存count的變量值爲6
致使兩個線程即便用volatile關鍵字修改以後,仍是會存在併發的狀況。
*/ 併發
//volatile告訴jvm, 它所修飾的變量不保留拷貝,直接訪問主內存中的(也就是上面說的A)
//在Java內存模型中,有main memory,每一個線程也有本身的memory (例如寄存器)。
//一個變量聲明爲volatile,就意味着這個變量是隨時會被其餘線程修改的,所以不能將它cache在線程memory中。 jvm
//所以volatile只是在線程內存和「主」內存間同步某個變量的值,而synchronized經過鎖定和解鎖某個監視器同步全部變量的值。
//顯然synchronized要比volatile消耗更多資源。 this
//在使用volatile關鍵字時要慎重,並非只要簡單類型變量使用volatile修飾,對這個變量的全部操做都是原來操做,
//當變量的值由自身的上一個決定時,如n=n+一、n++ 等,volatile關鍵字將失效。
//只有當變量的值和自身上一個值無關時對該變量的操做纔是原子級別的,如n = m + 1,這個就是原級別的。 spa
public class NewThreadTest {
public static volatile int count = 0;//定義類變量
private static Object obj = new Object();
public static void inc() {
//這裏延遲1毫秒,使得結果明顯
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
//synchronized (this) {//***************** static donot exist "this" object....
synchronized(obj){
count++;
System.out.println("運行結果:Counter.count"+count);
}
}
public static void main(String[] args) {
//同時啓動1000個線程,去進行i++計算,看看實際結果
for (int i = 0; i < 1000; i++) {
new Thread(new Runnable() {//匿名內部類調用靜態方法
public void run() {
NewThreadTest.inc();
}
}).start();
}
}
} 線程
用runnable的方法 進行實現 內存
public class MyRunnable implements Runnable {
private int count = 100;
public synchronized void run() {
count--;
System.out.println("count===="+count);
}
} 資源
public class MyTreadTest {
public static void main(String[] args) {
Runnable myrun = new MyRunnable();
for(int i=0;i<100;i++){
new Thread(myrun).start();
}
}
} 同步