久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Synchronized簡介與原理

 印度阿三17 2019-10-27

一,、作用

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

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

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

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

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

二,、用法

1. Java中的每個對象都可以作為鎖,,獲取的鎖都是對象

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

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

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

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

6. 作用域

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

b. 某個類的范圍,,一般是靜態(tà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)視器進入,,獲取鎖
         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指令實現(xiàn)

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

5. 無論哪種實現(xiàn),,本質(zhì)上都是對monitor的獲取,,這個過程是互斥的

四、鎖的狀態(tài)

1. 對象頭:

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

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

2. monitor:

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

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

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

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

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

c. 適用于沒有激烈競爭鎖的情況,不僅沒有多線程競爭,,而且總是由同一個線程獲取鎖

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

a. 獲取偏向鎖失敗后,,會膨脹為輕量級鎖

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

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

a. 獲取輕量級鎖失敗后,會膨脹為重量級鎖

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

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

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()時,需要先對對象加鎖

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

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

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

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

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

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多