Java併發之synchronized關鍵字和Lock介面
歡迎點贊閱讀,一同學習交流,有疑問請留言 。
GitHub上也有開源 JavaHouse,歡迎star
引用
當開發過程中,我們遇到併發問題。怎麼解決?
一種解決方式,簡單粗暴:上鎖。將千軍萬馬都給攔下來,只允許一個人過獨木橋。書面意思就是將並行的程式變成序列的程式。現實的鎖有門鎖、掛鎖和抽屜鎖等等。在Java中,我們的鎖就是synchronized關鍵字和Lock介面。
synchronized關鍵字
synchronized也叫同步鎖,是Java裡面的關鍵字。我們可以猜測到synchronized原理也JVM虛擬機器有關聯。
synchronized鎖的是物件。物件裡面有一個叫做監視鎖(monitor)的東西,監視鎖依賴作業系統的互斥鎖(Mutex Lock)。作業系統切換執行緒其實就是從使用者態程式設計核心態(cpu的兩種狀態)。這個代價有點高,所以synchronized這個重量級鎖後面也引進了偏向鎖和輕量級鎖。
加鎖(監視鎖monitor)過程分析():
- 當monitor的進入數為0,執行緒A進入
- monitor的進入數為1
- 執行緒B想進入該monitor就會被阻塞。
執行緒A可以重複進入該monitor,所以synchronized是可重入鎖,和Lock實現的鎖一樣。
- 程式驗證
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++; } } } }
- 執行結果
程式正常執行,沒有報錯
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(); } } }
- 執行結果
100000
如果去掉 synchronized 關鍵字的話,執行結果大概率不是 100000,因為執行緒不安全問題。
Lock介面
一般我們使用 ReentrantLock 類作為重入鎖,實現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("結果為:"+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();
}
}
}
}
- 執行結果
結果為:100000
這裡我們鎖住的 j++ 這塊資源區(公共資源),lock 是 static 關鍵字修飾的,是類物件,思考一下如果不是類物件會怎麼樣?那就是連環鎖了(看圖)。
每一個執行緒都對可以用鑰匙解開這把鎖,對於程式而言,加鎖操作就沒有意義了。因為我們需要的是一個鎖。
歡迎關注我的微信公眾號
相關推薦
Java併發之synchronized關鍵字和Lock介面
歡迎點贊閱讀,一同學習交流,有疑問請留言 。 GitHub上也有開源 JavaHouse,歡迎star 引用 當開發過程中,我們遇到併發問題。怎麼解決? 一種解決方式,簡單粗暴:上鎖。將千軍萬馬都給攔下來,只允許一個人過獨木橋。書面意思就是將並行的程式變成序列的程式。現實的鎖有門鎖、掛鎖和抽屜鎖等等。
Java併發之synchronized關鍵字深度解析(一)
前言 近期研讀路神之絕世武學,徜徉於浩瀚無垠知識之海洋,偶有攫取吉光片羽,惶恐未領略其精髓即隱入歲月深處,遂急忙記錄一二,順備來日吹cow之談資。本小系列為併發之親兒子-獨臂狂俠synchronized專場。 一、使用場景 &
Java多線程:synchronized關鍵字和Lock
final sleep java多線 大型 pre 有一個 但是 logs 讀寫文件 一、synchronized synchronized關鍵字可以用於聲明方法,也可以用來聲明代碼塊,下面分別看一下具體的場景(摘抄自《大型網站系統與Java中間件實踐》) 案例一:
Java多執行緒-併發之synchronized 關鍵字
synchronized 關鍵字 答: 底層實現: 進入時,執行 monitorenter,將計數器 +1,釋放鎖 monitorexit 時,計數器 -1 當一個執行緒判斷到計數器為 0 時,則當前鎖空閒,可以佔用;反之,當前執行緒進入等待狀態 含義
java併發之----volatile關鍵字
一、volatile 在java中,volatile關鍵字解決的是變數在多個執行緒之間的可見性,一旦一個共享變數(類的成員變數、類的靜態成員變數)被volatile修飾之後,那麼就具備了兩層語義: (1)保證了不同執行緒對這個變數進行操作時的可見性,即一個執行緒修改了某個變數的值,這
Java併發程式設計(六)Lock介面
一、Lock介面的引入 由於synchronized關鍵字有些缺陷,如無法響應中斷等,出現了Lock介面。相對於synchronized,Lock有如下補充: Lock可以響應中斷; Lock可以得知執行緒是否已經獲得鎖; Lock可以提供更為複雜的讀寫鎖,以應對讀寫同時存
Java中的transient關鍵字和Externalizable介面
一、transient transient 關鍵字可以應用於類的成員變數,以便指出該成員變數不應在包含它的類例項已序列化時被序列化。 若一個類中,有些屬性需要序列化,其他屬性不需要序列化,只要實現Serializable介面,將不需要序列化的屬性前新增關鍵字transien
java併發之----synchronized與ReenTrantLock
Java 提供了兩種鎖機制來控制多個執行緒對共享資源的互斥訪問,第一個是 JVM 實現的 synchronized,而另一個是 JDK 實現的 ReentrantLock。 synchronized synchronized關鍵字最主要幾種使用方式: (1)同步一個程式碼塊: 只作用
深入理解Java併發之synchronized實現原理
關聯文章: 本篇主要是對Java併發中synchronized關鍵字進行較為深入的探索,這些知識點結合博主對synchronized的個人理解以及相關的書籍的講解(在結尾參考資料),如有誤處,歡迎留言。 執行緒安全是併發程式
java併發程式設計---synchronized關鍵字
在併發程式設計中,多執行緒同時併發訪問的資源叫做臨界資源,當多個執行緒同時訪問物件並要求操作相同資源時,分割了原子操作就有可能出現數據的不一致或資料不完整的情況,為避免這種情況的發生,我們會採取同步機制,以確保在某一時刻,方法內只允許有一個執行緒。 採用syn
Java併發之AQS用法和原始碼分析
概念 AQS:佇列同步器AbstractQueuedSynchronizer(以下簡稱同步器),是用來構建鎖或者其他同步元件的基礎框架,許多同步器可以通過AQS很容易的並且高效的構建出來。不僅RenntrantLock和Semaphore是基於AQS構建的,還包括CountDownLat
原始碼閱讀:Java併發之synchronized實現原理
執行緒安全是併發程式設計中的重要關注點,應該注意到的是,造成執行緒安全問題的主要誘因有兩點,一是存在共享資料(也稱臨界資源),二是存在多條執行緒共同操作共享資料。因此為了解決這個問題,我們可能需要這樣一個方案,當存在多個執行緒操作共享資料時,需要保證同一時刻有且
深入理解 Java 併發之 synchronized 實現原理
關聯文章深入理解Java型別資訊(Class物件)與反射機制深入理解Java列舉型別(enum)深入理解Java註解型別(@Annotation)深入理解Java併發之synchronized實現原理本篇主要是對Java併發中synchronized關鍵字進行較為深入的探索,這些知識點結合博主對synchro
java 併發之 synchronized 實現原理
在 java 開發中 synchronized 是使用的最多的工具。 表現形式 在 java 中每個物件都可以作為鎖: 對於普通同步方法,鎖是當前例項物件; 對於靜態同步方法,鎖是當前類的 Class 物件; 對於同步方法快,鎖是 Synchronized 括
java基礎之Synchronized關鍵字
Java中Synchronized的用法 總結: A. 無論synchronized關鍵字加在方法上還是物件上,如果它作用的物件是非靜態的,則它取得的鎖是物件;如果synchronized作用的物件是一個靜態方法或一個類,則它取得的鎖是對類,該類所有的物件同一把鎖
Java併發之volatile關鍵字
引言 說到多執行緒,我覺得我們最重要的是要理解一個臨界區概念。 舉個例子,一個班上1個女孩子(臨界區),49個男孩子(執行緒),男孩子的目標就是這一個女孩子,就是會有競爭關係(執行緒安全問題)。推廣到實際場景,例如對一個數相加或者相減等等情形,因為操作物件就只有一個,在多執行緒環境下,就會產生執行緒安全問
《提升能力,漲薪可待》—Java併發之Synchronized
Synchronized簡介 執行緒安全是併發程式設計中的至關重要的,造成執行緒安全問題的主要原因: 臨界資源, 存在共享資料 多執行緒共同操作共享資料 而Java關鍵字synchronized,為多執行緒場景下防止臨界資源訪問衝突提供支援, 可以保證在同一時刻,只有一個執行緒可以執行某個方
java併發之synchronized
Java為我們提供了隱式(synchronized宣告方式)和顯式(java.util.concurrentAPI程式設計方式)兩種工具來避免執行緒爭用。 本章節探索Java關鍵字synchronized。主要包含以下幾個內容。 - synchronized關鍵字的使用; - synchronized背後
Java高併發程式設計之synchronized關鍵字(二)
上一篇文章講了synchronized的部分關鍵要點,詳見:Java高併發程式設計之synchronized關鍵字(一) 本篇文章接著講synchronized的其他關鍵點。 在使用synchronized關鍵字的時候,不要以字串常量作為鎖定物件。看下面的例子: public class
Java高併發程式設計之synchronized關鍵字(一)
首先看一段簡單的程式碼: public class T001 { private int count = 0; private Object o = new Object(); public void m() { //任何執行緒要執行下面這段程式碼