国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

Java并發(fā)編程系列(二)----synchronized鎖詳解

2019-11-14 08:45:53
字體:
供稿:網(wǎng)友

前面我們分析了volatile關(guān)鍵字,我們知道volatile關(guān)鍵字是無法保證線程安全的。那么java的線程安全主要由內(nèi)置的synchronized關(guān)鍵字和Locks包下的類來保證,Locks包下的類留到下一節(jié)再講。

關(guān)于synchronized,有兩種同步方式,一種是同步方法,另外一種是同步代碼塊,關(guān)于什么是同步代碼塊,什么是同步方法就不細(xì)講了,這里主要講講Java的內(nèi)置鎖。看一段代碼

package com.rancho945.concurrent;public class SynchronizedDemo { PRivate Object lockObject = new Object(); //A:同步方法 public synchronized void method1(){ } //B:同步靜態(tài)方法 public static synchronized void method2(){ } public void method3(){ //C:同步代碼塊 synchronized (lockObject) { } } public void method4(){ //D:同步代碼塊 synchronized (this) { } } //E:沒有同步 public void method5() { }}

很多小伙伴們?nèi)菀装焰i的各種表現(xiàn)形式搞蒙,其實(shí)只要記住兩點(diǎn)即可:

內(nèi)置鎖有兩種:一種是類鎖,另一種是對(duì)象鎖;類鎖只有一個(gè),不同的對(duì)象有不同的對(duì)象鎖。不同的鎖之間不互斥,線程可以并發(fā)執(zhí)行沒有互斥條件的代碼(廢話)。

看上面的代碼,A、B、C、三處的鎖是不同的,A和D是同一把鎖。A和D處的是SynchronizedDemo對(duì)象鎖,B是Synchronized類鎖,C是lockObject對(duì)象鎖,E沒有加鎖。

那么也就意味著:多線程可以同時(shí)執(zhí)行ABCE處的代碼,因?yàn)樗麄儧]有互斥條件。而A和D在同一時(shí)刻只能被一個(gè)線程執(zhí)行,因?yàn)樗麄兂钟械氖峭话焰i。

我們把上面的代碼加一點(diǎn)點(diǎn)料。

package com.rancho945.concurrent;public class SynchronizeDemo { private Object lockObject = new Object(); //臨界資源(共享變量) private static int count = 0; //A:同步方法 public synchronized void method1(){ count++; } //B:同步靜態(tài)方法 public static synchronized void method2(){ count++; } public void method3(){ //C:同步代碼塊 synchronized (lockObject) { count++; } } public void method4(){ //D:同步代碼塊 synchronized (this) { count++; } } //E:沒有同步 public void method5() { count++; }}

有可能被多個(gè)線程訪問到的資源,我們稱之為臨界資源或共享變量。這里的count變量就是屬于共享變量。那么在多線程的環(huán)境下,對(duì)count的操作是不安全的,比如某個(gè)線程執(zhí)行method1的時(shí)候,另外的線程執(zhí)行了method2或者3或者5。要想對(duì)count變量進(jìn)行線程安全的操作,那么所有操作count變量的都需要同一把鎖。 再看一個(gè)換湯不換藥的:

package com.rancho945.concurrent;public class SynchronizeDemo { private Object lockObject = new Object(); private SynchronizeDemo lockDemo = new SynchronizeDemo(); //臨界資源(共享資源) private static int count = 0; //A:同步方法 public synchronized void method1(){ count++; } //B:同步靜態(tài)方法 public static synchronized void method2(){ count++; } public void method3(){ //C:同步代碼塊 synchronized (lockObject) { count++; } } public void method4(){ //D:同步代碼塊 synchronized (this) { count++; } } //E:沒有同步 public void method5() { count++; } public void method6() { //F lockDemo.method1(); } public void method7() { //G lockDemo.method4(); } public void method8() { //H synchronized (lockDemo) { } } public void method9() { //I lockDemo.method3(); }}

這里的FGH都是同一把鎖,他們之間是互斥的,因?yàn)槭褂玫亩际莑ockDemo對(duì)象的鎖。而I與FGH不互斥,因?yàn)橛玫氖莑ockDemo中的lockObject對(duì)象的鎖

在發(fā)生異常的時(shí)候,JVM會(huì)自動(dòng)釋放鎖,因此不會(huì)因?yàn)楫惓6l(fā)生死鎖

那么我們開始思考,為什么鎖的設(shè)計(jì)會(huì)是放在對(duì)象上而不是放在線程上呢?

答案從我們的生活中找,比如說,你(線程)上廁所(對(duì)象),是自己每次都帶一把鎖還是廁所門上裝一把鎖?這道理同樣適合用于Java鎖的設(shè)計(jì),同時(shí)也更好地解釋了:

當(dāng)執(zhí)行Thread.sleep()的時(shí)候?yàn)槭裁床粫?huì)釋放鎖(相當(dāng)你在廁所睡著了,廁所還是鎖著的); wait方法是在Object上而不是Thread上(鎖在廁所門上而不是在你手上); 必須獲得對(duì)象鎖才能調(diào)用wait和notify、notifyAll方法(廁所門的鎖控制權(quán)在你手上你才能決定是否把廁所讓給別人用)。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 常德市| 广饶县| 灵丘县| 民乐县| 新营市| 南靖县| 板桥市| 五家渠市| 噶尔县| 江阴市| 从江县| 张掖市| 盘锦市| 潞西市| 乐亭县| 溧阳市| 神木县| 龙游县| 土默特右旗| 杭锦旗| 吉首市| 黑山县| 突泉县| 六安市| 彭阳县| 丰宁| 昌乐县| 陕西省| 大余县| 梁河县| 徐州市| 宁化县| 江北区| 白玉县| 葵青区| 阿尔山市| 怀柔区| 郸城县| 恩平市| 新宁县| 富阳市|