小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Synchronized簡(jiǎn)介與原理

 印度阿三17 2019-10-27

一、作用

1. 多線程同步代碼,保證方法或者代碼塊在運(yùn)行時(shí),同一時(shí)刻只有一個(gè)線程可以進(jìn)入到臨界區(qū)(互斥性)

2. 保證線程間共享變量的修改及時(shí)可見(jiàn)(可見(jiàn)性)

a. 當(dāng)線程獲取鎖時(shí),線程的本地變量無(wú)效,需要從主存中獲取共享變量的值

b. 線程釋放鎖時(shí),線程的本地變量被刷新到主存中

3. 有效解決重排序問(wèn)題(有序性)

二、用法

1. Java中的每個(gè)對(duì)象都可以作為鎖,獲取的鎖都是對(duì)象

2. 修飾函數(shù),即普通同步方法,鎖是當(dāng)前類(lèi)的實(shí)例對(duì)象 public void synchronized A(){}

3. 靜態(tài)同步方法,鎖是當(dāng)前類(lèi)的class對(duì)象 public static void synchronized A(){}

4. 修飾函數(shù)內(nèi)的語(yǔ)句塊,即同步代碼塊,鎖是括號(hào)中的對(duì)象 synchronized(obj){}

5. 每個(gè)對(duì)象只有一個(gè)鎖(lock)與之關(guān)聯(lián)

6. 作用域

a. 某個(gè)對(duì)象實(shí)例內(nèi)的方法,不同對(duì)象的實(shí)例內(nèi)的方法不相干擾,其他線程可以同時(shí)訪問(wèn)相同類(lèi)的其他對(duì)象實(shí)例中的synchronized方法

b. 某個(gè)類(lèi)的范圍,一般是靜態(tài)方法,可以防止多個(gè)線程同時(shí)訪問(wèn)相同類(lèi)中的synchronized方法

三、原理

1. java示例代碼,同步靜態(tài)方法

public class SynchronizedTest {
    private static Object object = new Object();
    public static void main(String[] args) throws Exception{
        synchronized(object) {
            
        }
    }
    public static synchronized void m() {}
}

2. 代碼->字節(jié)碼->反編譯后的代碼

public static void main(java.lang.String[]) throws java.lang.Exception;
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: getstatic     #2                  // Field object:Ljava/lang/Object

         3: dup
         4: astore_1
         5: monitorenter            //監(jiān)視器進(jìn)入,獲取鎖
         6: aload_1
         7: monitorexit              //監(jiān)視器退出,釋放鎖
         8: goto          16
        11: astore_2
        12: aload_1
        13: monitorexit
        14: aload_2
        15: athrow
        16: return
     
   public static synchronized void m();
   descriptor: ()V
   flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
   Code:
     stack=0, locals=0, args_size=0
        0: return
     LineNumberTable:
       line 9: 0

3. 同步代碼塊使用monitorenter和monitorexit指令實(shí)現(xiàn)

4. 同步方法使用修飾符ACC_SYNCHRONIZED實(shí)現(xiàn)

5. 無(wú)論哪種實(shí)現(xiàn),本質(zhì)上都是對(duì)monitor的獲取,這個(gè)過(guò)程是互斥的

四、鎖的狀態(tài)

1. 對(duì)象頭:

a. 對(duì)象在內(nèi)存中分為3部分:對(duì)象頭、實(shí)例數(shù)據(jù)、對(duì)齊填充

b. 對(duì)象頭可以記錄對(duì)象的狀態(tài):偏向鎖、輕量級(jí)鎖、重量級(jí)鎖

2. monitor:

a. 線程私有的數(shù)據(jù)結(jié)構(gòu),每個(gè)線程有一個(gè)monitor列表

b. JVM記錄獲取monitor鎖的線程唯一id,確保一次只有一個(gè)線程執(zhí)行

3. 偏向鎖狀態(tài):

a. 如果一個(gè)線程獲取了鎖,那么鎖就進(jìn)入了偏向狀態(tài)

b. 當(dāng)這個(gè)線程再次請(qǐng)求鎖時(shí),不需要再做同步,就可以獲取鎖,避免了申請(qǐng)鎖的操作,優(yōu)化了性能

c. 適用于沒(méi)有激烈競(jìng)爭(zhēng)鎖的情況,不僅沒(méi)有多線程競(jìng)爭(zhēng),而且總是由同一個(gè)線程獲取鎖

4. 輕量級(jí)鎖狀態(tài):

a. 獲取偏向鎖失敗后,會(huì)膨脹為輕量級(jí)鎖

b. 適用于交替執(zhí)行同步塊的情況

5. 重量級(jí)鎖狀態(tài):

a. 獲取輕量級(jí)鎖失敗后,會(huì)膨脹為重量級(jí)鎖

b. 此時(shí)所有線程都會(huì)被鎖住,當(dāng)前獲取鎖的線程釋放后,其他線程才被喚醒

五、等待通知機(jī)制,即wait(),notify(),notifyall()進(jìn)行線程間通信

1. 代碼

public class WaitNotify {
    static boolean flag = true;
    static Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread A = new Thread(new Wait(), "wait thread");
        A.start();
        TimeUnit.SECONDS.sleep(2);
        Thread B = new Thread(new Notify(), "notify thread");
        B.start();
    }

    static class Wait implements Runnable {
        @Override
        public void run() {
            synchronized (lock) {
                while (flag) {
                    try {
                        System.out.println(Thread.currentThread()   " flag is true");
                        lock.wait();
                    } catch (InterruptedException e) {

                    }
                }
                System.out.println(Thread.currentThread()   " flag is false");
            }
        }
    }

    static class Notify implements Runnable {
        @Override
        public void run() {
            synchronized (lock) {
                flag = false;
                lock.notifyAll();
                try {
                    TimeUnit.SECONDS.sleep(7);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

2. 使用wait(),notify(),notifyAll()時(shí),需要先對(duì)對(duì)象加鎖

3. 調(diào)用wait()方法后,線程會(huì)釋放鎖,線程狀態(tài)RUNNING->WAITING,將線程移動(dòng)到等待隊(duì)列

4. notify()/notifyAll()時(shí),等待線程不會(huì)立即從wait()返回,需要當(dāng)前線程釋放鎖之后,才有機(jī)會(huì)獲取鎖返回

5. notify()將一個(gè)等待隊(duì)列里的線程,移動(dòng)到同步隊(duì)列,線程狀態(tài)WAITING->BLOCKED

6. notifyAll()將所有等待隊(duì)列里的線程,移動(dòng)到同步隊(duì)列,線程狀態(tài)WAITING->BLOCKED

7. 線程只有獲取了鎖,才能從wait()返回

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多