Java多線程(二)--synchronized關(guān)鍵字簡析

本篇來自慕課網(wǎng)"悟空"視頻的筆記。先簡單介紹一下synchronized您没。

在Java中,每個對象有且僅有一個同步鎖蒲列。不同的線程對同步鎖的訪問是互斥的忽媒,即同一時刻争拐,僅有一個線程可以得到該鎖。所以晦雨,我們可以以同步鎖為基礎(chǔ)架曹,實現(xiàn)多線程間對共享數(shù)據(jù)操作的可見性和原子性。使用同步鎖有幾種方式闹瞧,synchronized就是其中之一绑雄。

簡單介紹

synchronized是Java的一個關(guān)鍵字,是學(xué)習(xí)并發(fā)編程繞不開的一個知識點奥邮。它可以防止線程干擾和內(nèi)存一致性錯誤万牺,保證同一時刻最多只有一個線程執(zhí)行某段被鎖住的代碼罗珍,以保證并發(fā)安全。

用法

對象鎖

包括方法鎖(默認(rèn)對象為this當(dāng)前實例對象)和同步代碼塊鎖杏愤。

同步代碼塊鎖:

synchronized(this) {
            System.out.println("對象鎖中的同步代碼塊鎖靡砌。線程名為:" + Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "運行結(jié)束");
}

此處,通過this鎖住當(dāng)前對象珊楼。有一點要注意:此處如果是通過繼承Thread的方式創(chuàng)建了線程通殃,那么每次都會有不同的this對象。因此厕宗,此處的synchronized沒有作用画舌。

方法鎖:

public synchronized void test(){

System.out.println("對象鎖中的方法鎖。線程名為:" + Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "運行結(jié)束");

}

方法鎖的默認(rèn)鎖對象為this已慢。

以上就是對象鎖的兩種形式曲聂,其中,在同步代碼塊鎖中佑惠,我們不僅可以使用this朋腋,還可以自定義一個鎖對象,比如:

Object obj = new Object();
synchronized(obj) {
            System.out.println("對象鎖中的同步代碼塊鎖膜楷。線程名為:" + Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "運行結(jié)束");
}

類鎖

指synchronized修飾靜態(tài)的方法或者指定鎖為Class對象旭咽。

靜態(tài)鎖

 private static synchronized void test() {
            System.out.println("我是類鎖中的靜態(tài)鎖。線程名為:" + Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "運行結(jié)束");
    }

與方法鎖不同的是赌厅,此方法為static修飾的靜態(tài)方法穷绵。

Class對象鎖

//此處假設(shè)我們有一個MyTest類
synchronized(MyTest.class) {
            System.out.println("對象鎖中的同步代碼塊鎖。線程名為:" + Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

以上就是類鎖的兩種形式特愿,與方法鎖不同的地方在于仲墨,類鎖的對象為當(dāng)前類。

注意:

1揍障、一把鎖只能同時被一個線程獲取目养,沒有拿到鎖的線程只能等待

2、每個實例都對應(yīng)有自己的一把鎖毒嫡,不同實例之間互不影響

3癌蚁、在方法執(zhí)行完畢或者拋出異常后,會釋放鎖

性質(zhì)

可重入性

指同一線程的外層函數(shù)獲得鎖后审胚,內(nèi)層函數(shù)可以直接再次獲取該鎖

好處:避免死鎖匈勋,提升封裝性

粒度:與線程相關(guān),與調(diào)用無關(guān)

不可中斷性

一旦一個鎖被其他線程獲得膳叨,其他的線程如果想獲得該鎖洽洁,就會等待或被阻塞,直到鎖被釋放菲嘴。如果鎖沒有被釋放饿自,等待的線程會永遠(yuǎn)等待下去汰翠。

加鎖和釋放鎖的原理

可重入原理:加鎖次數(shù)計數(shù)器。JVM負(fù)責(zé)跟蹤對象被加鎖的次數(shù)昭雌;線程第一次給對象加鎖的時候复唤,計數(shù)變?yōu)?.每當(dāng)這個相同的線程再次獲得該鎖時,計數(shù)器會遞增烛卧;每當(dāng)任務(wù)離開佛纫,計數(shù)遞減,當(dāng)技術(shù)為0的時候总放,鎖被釋放呈宇。

保證可見性的原理:內(nèi)存模型

通過反編譯看字節(jié)碼:javap -verbose hello.class

synchronized有個加鎖的monitorenter和解鎖的monitorexit,讀到指令局雄,會讓monitor計數(shù)器加一或者減一甥啄。

缺陷

1、效率低炬搭,鎖的釋放情況少蜈漓,一種是正常執(zhí)行任務(wù)完釋放,一種是異常JVM釋放宫盔,不能設(shè)置超時時間融虽;

2、不夠靈活飘言,讀的話可能不需要加鎖衣形,例如讀寫鎖就比較靈活驼侠;

3姿鸿、無法判斷狀態(tài),是否獲取到鎖

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末倒源,一起剝皮案震驚了整個濱河市苛预,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌笋熬,老刑警劉巖热某,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異胳螟,居然都是意外死亡昔馋,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門糖耸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秘遏,“玉大人,你說我怎么就攤上這事嘉竟“钗#” “怎么了洋侨?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長倦蚪。 經(jīng)常有香客問我希坚,道長,這世上最難降的妖魔是什么陵且? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任裁僧,我火速辦了婚禮,結(jié)果婚禮上慕购,老公的妹妹穿的比我還像新娘锅知。我一直安慰自己,他們只是感情好脓钾,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布售睹。 她就那樣靜靜地躺著,像睡著了一般可训。 火紅的嫁衣襯著肌膚如雪昌妹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天握截,我揣著相機與錄音飞崖,去河邊找鬼。 笑死谨胞,一個胖子當(dāng)著我的面吹牛固歪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胯努,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼牢裳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了叶沛?” 一聲冷哼從身側(cè)響起蒲讯,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎灰署,沒想到半個月后判帮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡溉箕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年晦墙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肴茄。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡晌畅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出独郎,到底是詐尸還是另有隱情踩麦,我是刑警寧澤枚赡,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站谓谦,受9級特大地震影響贫橙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜反粥,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一卢肃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧才顿,春花似錦莫湘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至尾组,卻和暖如春忙芒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背讳侨。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工呵萨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人跨跨。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓潮峦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親勇婴。 傳聞我的和親對象是個殘疾皇子忱嘹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349