在多線程中,同步關(guān)鍵字synchronized 加鎖的對(duì)象是在 對(duì)象. 如果要 類 級(jí)別加鎖,要給該類加上final
在多個(gè)線程中,對(duì)于變量實(shí)現(xiàn) 同步共享的時(shí)候,可以使用volatile.
1.在JAVA1.5以后,每一個(gè)線程都會(huì)有一塊工作內(nèi)存區(qū),其中存放著所有線程共享的主內(nèi)存中的變量值的拷貝.當(dāng)線程執(zhí)行時(shí),它在自己的工作內(nèi)存區(qū)中操作這些變量.為了存取一個(gè)共享的變量,一個(gè)線程通常先獲取鎖定并去清除它的內(nèi)存工作區(qū).把這些共享變量從所有線程共享的內(nèi)存工作區(qū)正確的裝載到自己的內(nèi)存工作區(qū).當(dāng)線程解鎖時(shí),保證該內(nèi)存工作區(qū)中的變量寫回到共享的內(nèi)存區(qū).
2.一個(gè)線程可以執(zhí)行的操作有使用,賦值,裝載,存儲(chǔ),鎖定,解鎖.
3.而主內(nèi)存可以執(zhí)行的操作有:讀,寫,鎖定,解鎖. 每個(gè)操作都是原子的.
而volatile就是強(qiáng)制線程到主內(nèi)存區(qū) 去讀取變量,而不去線程工作區(qū)讀取.從而實(shí)現(xiàn)了 多個(gè)線程間的變量可見.也就滿足了線程安全的可見性.
public class RunThread extends Thread {
private boolean isRunning = true;
//private volatile boolean isRunning = true;
@Override
public void run() {
super.run();
System.out.println("go into run method.....");
while(isRunning == true){
}
System.out.println("thread stop.....");
}
public static void main(String[] args) throws Exception{
RunThread rt = new RunThread();
rt.start();
Thread.sleep(1000);
rt.isRunning = false;
System.out.println("isRunning set value false");
Thread.sleep(1000);
System.out.println(rt.isRunning);
}
}
volatile 關(guān)鍵字是非原子性的.
雖然它可以讓變量在多個(gè)線程見可見,但是卻不具備同步性.可以算是一個(gè)輕量級(jí)的synchronized.性能比synchronized 強(qiáng)很多,不會(huì)造成阻塞.
所以說 volatile對(duì)比synchronized具備可見性,不具備同步性. 如果要做同步的操作,只能用synchronized.
代碼貼這里:
package lee.thread;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/**本示例說明volatile不具備原子性
1.不加volatile關(guān)鍵詞
2.加上volatile關(guān)鍵詞修飾代碼2 (多運(yùn)行幾次,出現(xiàn)最大值不是10000),說明volatile不具備原子性3. 用代碼1 的兩行. 最大值一定是10000*/
public class VolatileNoAtomic extends Thread{
//private static AtomicInteger count = new AtomicInteger(0);//1
private static volatile int count = 0;//2
public static void addCount(){
for(int i=0;i < 1000; i++){
//count.incrementAndGet(); //1
count++;
}
System.out.println(count);
}
@Override
public void run() {
super.run();
addCount();
}
public static void main(String[] args) {
VolatileNoAtomic[] arr = new VolatileNoAtomic[10];
for(int i=0;i<10;i++){
arr[i]=new VolatileNoAtomic();
}
for(int i=0;i<10;i++){
arr[i].start();
}
//ConcurrentHashMap<K, V> map = new ConcurrentHashMap<>();
}
}