1、volatile和synchronized的區(qū)別
volatile本質(zhì)是在告訴jvm當(dāng)前變量在寄存器(工作內(nèi)存)中的值是不確定的,需要從主存中讀确邪妗嘁傀;
synchronized則是鎖定當(dāng)前變量,只有當(dāng)前線程可以訪問(wèn)該變量视粮,其他線程被阻塞住细办。
volatile僅能使用在變量級(jí)別;synchronized則可以使用在變量馒铃、方法蟹腾、和類(lèi)級(jí)別的
volatile僅能實(shí)現(xiàn)變量的修改可見(jiàn)性,不能保證原子性区宇;而synchronized則可以保證變量的修改可見(jiàn)性和原子性
volatile不會(huì)造成線程的阻塞娃殖;synchronized可能會(huì)造成線程的阻塞。
volatile標(biāo)記的變量不會(huì)被編譯器優(yōu)化议谷;synchronized標(biāo)記的變量可以被編譯器優(yōu)化
2炉爆、通過(guò)靜態(tài)內(nèi)部類(lèi)實(shí)現(xiàn)單例好處
1、不用synchronized卧晓,節(jié)省時(shí)間
2芬首、懶加載,節(jié)省空間
3逼裆、synchronized三種用法
對(duì)于普通同步方法郁稍,鎖是當(dāng)前實(shí)例對(duì)象
對(duì)于靜態(tài)同步方法,鎖是當(dāng)前類(lèi)Class對(duì)象
對(duì)于同步方法塊胜宇,鎖是synchrionized括號(hào)里配置對(duì)象
//鎖的三種用法
public class SyncDemo {
private Object lock = new Object();
private static Object sLock = new Object();
public synchronized void methodInstance() {
System.out.println( "鎖是當(dāng)前實(shí)例對(duì)象" );
}
public synchronized static void methodClass() {
System.out.println( "鎖是當(dāng)前類(lèi)Class對(duì)象" );
}
public static void methodConfig() {
synchronized (SyncDemo.class) {
System.out.println( "鎖是synchronized配置對(duì)象 - 當(dāng)前類(lèi)Class對(duì)象" );
}
}
public static void methodConfig3() {
synchronized (sLock) {
System.out.println( "鎖是synchronized配置對(duì)象" );
}
}
public void methodConfig1() {
synchronized (lock) {
System.out.println( "鎖是synchronized配置對(duì)象" );
}
}
public void methodConfig2() {
synchronized (this) {
System.out.println( "鎖是synchronized配置對(duì)象 - 當(dāng)前實(shí)例對(duì)象" );
}
}
public static void main(String[] args) {
SyncDemo demo = new SyncDemo();
//當(dāng)前實(shí)例對(duì)象
demo.methodInstance();
demo.methodConfig2();
System.out.println();
//當(dāng)前類(lèi)Class對(duì)象
SyncDemo.methodClass();
SyncDemo.methodConfig();
System.out.println();
//配置對(duì)象
SyncDemo.methodConfig3();
demo.methodConfig1();
}
}