欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java的Synchronized關(guān)鍵字學(xué)習(xí)指南(全面 & 詳細(xì))

 更新時(shí)間:2021年03月05日 10:16:16   作者:Carson_Ho  
這篇文章主要給大家介紹了關(guān)于Java的Synchronized關(guān)鍵字的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

在Java中,有一個(gè)常被忽略 但 非常重要的關(guān)鍵字Synchronized今天,我將詳細(xì)講解 Java關(guān)鍵字Synchronized的所有知識(shí),希望你們會(huì)喜歡

目錄

示意圖

1. 定義

Java中的1個(gè)關(guān)鍵字

2. 作用

保證同一時(shí)刻最多只有1個(gè)線程執(zhí)行 被Synchronized修飾的方法 / 代碼

其他線程 必須等待當(dāng)前線程執(zhí)行完該方法 / 代碼塊后才能執(zhí)行該方法 / 代碼塊

3. 應(yīng)用場(chǎng)景

保證線程安全,解決多線程中的并發(fā)同步問(wèn)題(實(shí)現(xiàn)的是阻塞型并發(fā)),具體場(chǎng)景如下:

修飾 實(shí)例方法 / 代碼塊時(shí),(同步)保護(hù)的是同一個(gè)對(duì)象方法的調(diào)用 & 當(dāng)前實(shí)例對(duì)象修飾 靜態(tài)方法 / 代碼塊時(shí),(同步)保護(hù)的是 靜態(tài)方法的調(diào)用 & class 類(lèi)對(duì)象

4. 原理

依賴(lài) JVM 實(shí)現(xiàn)同步底層通過(guò)一個(gè)監(jiān)視器對(duì)象(monitor)完成, wait()、notify() 等方法也依賴(lài)于 monitor 對(duì)象

監(jiān)視器鎖(monitor)的本質(zhì) 依賴(lài)于 底層操作系統(tǒng)的互斥鎖(Mutex Lock)實(shí)現(xiàn)

5. 具體使用

Synchronized 用于 修飾 代碼塊、類(lèi)的實(shí)例方法 & 靜態(tài)方法

5.1 使用規(guī)則

示意圖

5.2 鎖的類(lèi)型 & 等級(jí) 由于Synchronized 會(huì)修飾 代碼塊、類(lèi)的實(shí)例方法 & 靜態(tài)方法,故分為不同鎖的類(lèi)型具體如下

示意圖

之間的區(qū)別

示意圖

5.3 使用方式

/**
 * 對(duì)象鎖
 */
 public class Test{ 
 // 對(duì)象鎖:形式1(方法鎖) 
 public synchronized void Method1(){ 
  System.out.println("我是對(duì)象鎖也是方法鎖"); 
  try{ 
   Thread.sleep(500); 
  } catch (InterruptedException e){ 
   e.printStackTrace(); 
  } 
 
 } 
 
 // 對(duì)象鎖:形式2(代碼塊形式) 
 public void Method2(){ 
  synchronized (this){ 
   System.out.println("我是對(duì)象鎖"); 
   try{ 
    Thread.sleep(500); 
   } catch (InterruptedException e){ 
    e.printStackTrace(); 
   } 
  } 
 
 } 
 }

/**
 * 方法鎖(即對(duì)象鎖中的形式1)
 */
 public synchronized void Method1(){ 
  System.out.println("我是對(duì)象鎖也是方法鎖"); 
  try{ 
   Thread.sleep(500); 
  } catch (InterruptedException e){ 
   e.printStackTrace(); 
  } 
 
 } 

/**
 * 類(lèi)鎖
 */
public class Test{ 
   // 類(lèi)鎖:形式1 :鎖靜態(tài)方法
 public static synchronized void Method1(){ 
  System.out.println("我是類(lèi)鎖一號(hào)"); 
  try{ 
   Thread.sleep(500); 
  } catch (InterruptedException e){ 
   e.printStackTrace(); 
  } 
 
 } 
 
 // 類(lèi)鎖:形式2 :鎖靜態(tài)代碼塊
 public void Method2(){ 
  synchronized (Test.class){ 
   System.out.println("我是類(lèi)鎖二號(hào)"); 
   try{ 
    Thread.sleep(500); 
   } catch (InterruptedException e){ 
    e.printStackTrace(); 
   } 
 
  } 
 
 } 
}

5.4 特別注意

Synchronized修飾方法時(shí)存在缺陷:若修飾1個(gè)大的方法,將會(huì)大大影響效率

示例

若使用Synchronized關(guān)鍵字修飾 線程類(lèi)的run(),由于run()在線程的整個(gè)生命期內(nèi)一直在運(yùn)行,因此將導(dǎo)致它對(duì)本類(lèi)任何Synchronized方法的調(diào)用都永遠(yuǎn)不會(huì)成功

解決方案

使用 Synchronized關(guān)鍵字聲明代碼塊

該解決方案靈活性高:可針對(duì)任意代碼塊 & 任意指定上鎖的對(duì)象

代碼如下
 synchronized(syncObject) { 
 // 訪問(wèn)或修改被鎖保護(hù)的共享狀態(tài) 
 // 上述方法 必須 獲得對(duì)象 syncObject(類(lèi)實(shí)例或類(lèi))的鎖
}

6. 特點(diǎn)

示意圖

注:原子性、可見(jiàn)性、有序性的定義

示意圖

7. 其他控制并發(fā) / 線程同步方式

7.1 Lock、ReentrantLock 簡(jiǎn)介

示意圖

區(qū)別

示意圖

7.2 CAS

7.2.1 定義

Compare And Swap,即 比較 并 交換,是一種解決并發(fā)操作的樂(lè)觀鎖

synchronized鎖住的代碼塊:同一時(shí)刻只能由一個(gè)線程訪問(wèn),屬于悲觀鎖

7.2.2 原理

// CAS的操作參數(shù)
內(nèi)存位置(A)
預(yù)期原值(B)
預(yù)期新值(C)

// 使用CAS解決并發(fā)的原理:
// 1. 首先比較A、B,若相等,則更新A中的值為C、返回True;若不相等,則返回false;
// 2. 通過(guò)死循環(huán),以不斷嘗試嘗試更新的方式實(shí)現(xiàn)并發(fā)

// 偽代碼如下
public boolean compareAndSwap(long memoryA, int oldB, int newC){
 if(memoryA.get() == oldB){
  memoryA.set(newC);
  return true;
 }
 return false;
}


7.2.3 優(yōu)點(diǎn)

資源耗費(fèi)少:相對(duì)于synchronized,省去了掛起線程、恢復(fù)線程的開(kāi)銷(xiāo)

但,若遲遲得不到更新,死循環(huán)對(duì)CPU資源也是一種浪費(fèi)

7.2.4 具體實(shí)現(xiàn)方式 使用CAS有個(gè)“先檢查后執(zhí)行”的操作而這種操作在Java中是典型的不安全的操作,所以 CAS在實(shí)際中是由C++通過(guò)調(diào)用CPU指令實(shí)現(xiàn)的具體過(guò)程

// 1. CAS在Java中的體現(xiàn)為Unsafe類(lèi)
// 2. Unsafe類(lèi)會(huì)通過(guò)C++直接獲取到屬性的內(nèi)存地址
// 3. 接下來(lái)CAS由C++的Atomic::cmpxchg系列方法實(shí)現(xiàn)

7.2.5 典型應(yīng)用:AtomicInteger

對(duì) i++ 與 i–,通過(guò)compareAndSet & 一個(gè)死循環(huán)實(shí)現(xiàn)

compareAndSet函數(shù)內(nèi)部 = 通過(guò)jni操作CAS指令。直到CAS操作成功跳出循環(huán)

 private volatile int value; 
 /** 
  * Gets the current value. 
  * 
  * @return the current value 
  */ 
 public final int get() { 
  return value; 
 } 
 /** 
  * Atomically increments by one the current value. 
  * 
  * @return the previous value 
  */ 
 public final int getAndIncrement() { 
  for (;;) { 
   int current = get(); 
   int next = current + 1; 
   if (compareAndSet(current, next)) 
    return current; 
  } 
 } 
 
 /** 
  * Atomically decrements by one the current value. 
  * 
  * @return the previous value 
  */ 
 public final int getAndDecrement() { 
  for (;;) { 
   int current = get(); 
   int next = current - 1; 
   if (compareAndSet(current, next)) 
    return current; 
  } 
 }

8. 總結(jié)

本文主要對(duì)Java中常被忽略 但 非常重要的關(guān)鍵字Synchronized進(jìn)行講解

到此這篇關(guān)于Java的Synchronized關(guān)鍵字學(xué)習(xí)指南的文章就介紹到這了,更多相關(guān)Java的Synchronized關(guān)鍵字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中線程安全有哪些實(shí)現(xiàn)思路

    Java中線程安全有哪些實(shí)現(xiàn)思路

    在 Java 多線程編程中,線程安全是一個(gè)非常重要的概念,本文主要介紹了Java中線程安全有哪些實(shí)現(xiàn)思路,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2023-05-05
  • 詳解Springboot整合Dubbo之代碼集成和發(fā)布

    詳解Springboot整合Dubbo之代碼集成和發(fā)布

    本篇文章主要介紹了Springboot整合Dubbo之代碼集成和發(fā)布,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • 一小時(shí)迅速入門(mén)Mybatis之bind與多數(shù)據(jù)源支持 Java API

    一小時(shí)迅速入門(mén)Mybatis之bind與多數(shù)據(jù)源支持 Java API

    這篇文章主要介紹了一小時(shí)迅速入門(mén)Mybatis之bind與多數(shù)據(jù)源支持 Java API,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Spring中propagation的7種事務(wù)配置及說(shuō)明

    Spring中propagation的7種事務(wù)配置及說(shuō)明

    這篇文章主要介紹了Spring中propagation的7種事務(wù)配置及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java中樹(shù)的存儲(chǔ)結(jié)構(gòu)實(shí)現(xiàn)示例代碼

    Java中樹(shù)的存儲(chǔ)結(jié)構(gòu)實(shí)現(xiàn)示例代碼

    本篇文章主要介紹了Java中樹(shù)的存儲(chǔ)結(jié)構(gòu)實(shí)現(xiàn)示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • SpringBoot+MySQL實(shí)現(xiàn)讀寫(xiě)分離的多種具體方案

    SpringBoot+MySQL實(shí)現(xiàn)讀寫(xiě)分離的多種具體方案

    在高并發(fā)和大數(shù)據(jù)量的場(chǎng)景下,數(shù)據(jù)庫(kù)成為了系統(tǒng)的瓶頸。為了提高數(shù)據(jù)庫(kù)的處理能力和性能,讀寫(xiě)分離成為了一種常用的解決方案,本文將介紹在Spring?Boot項(xiàng)目中實(shí)現(xiàn)MySQL數(shù)據(jù)庫(kù)讀寫(xiě)分離的多種具體方案,需要的朋友可以參考下
    2023-06-06
  • java大數(shù)乘法的簡(jiǎn)單實(shí)現(xiàn) 浮點(diǎn)數(shù)乘法運(yùn)算

    java大數(shù)乘法的簡(jiǎn)單實(shí)現(xiàn) 浮點(diǎn)數(shù)乘法運(yùn)算

    大數(shù)乘法可以進(jìn)行任意大小和精度的整數(shù)和浮點(diǎn)數(shù)的乘法運(yùn)算, 精確度很高, 可以用作經(jīng)融等領(lǐng)域的計(jì)算,這個(gè)是我看了一些資料, 然后自己整理實(shí)現(xiàn)的,簡(jiǎn)單測(cè)試了一下
    2014-01-01
  • java使用httpclient 發(fā)送請(qǐng)求的示例

    java使用httpclient 發(fā)送請(qǐng)求的示例

    HttpClient 是Apache Jakarta Common 下的子項(xiàng)目,可以用來(lái)提供高效的、最新的、功能豐富的支持 HTTP 協(xié)議的客戶(hù)端編程工具包,并且它支持 HTTP 協(xié)議最新的版本和建議,這篇文章主要介紹了java使用httpclient 發(fā)送請(qǐng)求的示例,需要的朋友可以參考下
    2023-10-10
  • Java面向?qū)ο蠡A(chǔ),類(lèi),變量,方法

    Java面向?qū)ο蠡A(chǔ),類(lèi),變量,方法

    這篇文章主要介紹了Java面向?qū)ο蠡A(chǔ),類(lèi),變量,方法,需要的朋友可以參考下
    2020-10-10
  • Java字節(jié)流 從文件輸入輸出到文件過(guò)程解析

    Java字節(jié)流 從文件輸入輸出到文件過(guò)程解析

    這篇文章主要介紹了Java字節(jié)流 從文件輸入 輸出到文件過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09

最新評(píng)論