溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java中synchronized關(guān)鍵字和Lock接口的實(shí)現(xiàn)原理是什么

發(fā)布時(shí)間:2021-07-23 16:02:19 來源:億速云 閱讀:156 作者:Leah 欄目:編程語言

本篇文章給大家分享的是有關(guān)Java中synchronized關(guān)鍵字和Lock接口的實(shí)現(xiàn)原理是什么,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

synchronized關(guān)鍵字

synchronized也叫同步鎖,是Java里面的關(guān)鍵字。我們可以猜測(cè)到synchronized原理也JVM虛擬機(jī)有關(guān)聯(lián)。

synchronized鎖的是對(duì)象。對(duì)象里面有一個(gè)叫做監(jiān)視鎖(monitor)的東西,監(jiān)視鎖依賴操作系統(tǒng)的互斥鎖(Mutex Lock)。操作系統(tǒng)切換線程其實(shí)就是從用戶態(tài)編程核心態(tài)(cpu的兩種狀態(tài))。這個(gè)代價(jià)有點(diǎn)高,所以synchronized這個(gè)重量級(jí)鎖后面也引進(jìn)了偏向鎖和輕量級(jí)鎖。

加鎖(監(jiān)視鎖monitor)過程分析():

當(dāng)monitor的進(jìn)入數(shù)為0,線程A進(jìn)入  monitor的進(jìn)入數(shù)為1  線程B想進(jìn)入該monitor就會(huì)被阻塞。

線程A可以重復(fù)進(jìn)入該monitor,所以synchronized是可重入鎖,和Lock實(shí)現(xiàn)的鎖一樣。

程序驗(yàn)證

public class SynchronizedTest {  private static int i = 0;  public static void main(String[] args) {    test();  }  public static void test(){    synchronized (SynchronizedTest.class){      synchronized (SynchronizedTest.class){        i++;      }    }  }}

運(yùn)行結(jié)果

程序正常運(yùn)行,沒有報(bào)錯(cuò)

synchronized可以修飾方法以及代碼塊,代碼塊就是上面重入鎖的例子。

修飾方法

public class SynchronizedTest {  static int n = 100;  final static CountDownLatch start = new CountDownLatch(n);  private static int i = 0;  public static void main(String[] args) throws InterruptedException {    for (int j = 0; j < n; j++) {      Thread thread = new Thread(new addNoSynchronized());      thread.start();    }    start.await();    System.out.println(i);  }  public static class addSynchronized implements Runnable{    @Override    public void run() {      addSynchronized();    }    public static synchronized void addSynchronized(){      for (int j = 0; j < 1000; j++) {        i++;      }      start.countDown();    }  }}

運(yùn)行結(jié)果

100000

如果去掉 synchronized 關(guān)鍵字的話,運(yùn)行結(jié)果大概率不是 100000,因?yàn)榫€程不安全問題。

Lock接口

一般我們使用 ReentrantLock 類作為重入鎖,實(shí)現(xiàn)Lock接口。

使用方法

public class ReentranLockTest {  private static int j;  private static int n = 100;  private static CountDownLatch latch = new CountDownLatch(n);  public static void main(String[] args) throws InterruptedException {    for (int i = 0; i < n; i++) {      new Thread(new LockTest()).start();    }    latch.await();    System.out.println("結(jié)果為:"+j);  }  public static class LockTest implements Runnable{    static Lock lock = new ReentrantLock();    @Override    public void run() {      lockTest();      latch.countDown();    }    private void lockTest() {      lock.lock();      try {        for (int i = 0; i < 1000; i++) {            j++;        }      }finally {        lock.unlock();      }    }  }}

運(yùn)行結(jié)果

結(jié)果為:100000

這里我們鎖住的 j++ 這塊資源區(qū)(公共資源),lock 是 static 關(guān)鍵字修飾的,是類對(duì)象,思考一下如果不是類對(duì)象會(huì)怎么樣?那就是連環(huán)鎖了(看圖)。

每一個(gè)線程都對(duì)可以用鑰匙解開這把鎖,對(duì)于程序而言,加鎖操作就沒有意義了。因?yàn)槲覀冃枰氖且粋€(gè)鎖。

以上就是Java中synchronized關(guān)鍵字和Lock接口的實(shí)現(xiàn)原理是什么,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI