偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

聊聊Synchronized的優(yōu)化

系統(tǒng)
在早期版本中,synchronized是一種重量級(jí)鎖,其底層由Monitor實(shí)現(xiàn),而Monitor又依賴于操作系統(tǒng)的Mutex Lock。線程獲取到鎖后,需要切換狀態(tài),而操作系統(tǒng)在實(shí)現(xiàn)線程的切換時(shí),需要從用戶態(tài)轉(zhuǎn)為核心態(tài),這是一個(gè)非常耗時(shí),非常重的操作。

[[375798]]

 早期版本synchronized性能較低的原因

在早期版本中,synchronized是一種重量級(jí)鎖,其底層由Monitor實(shí)現(xiàn),而Monitor又依賴于操作系統(tǒng)的Mutex Lock。線程獲取到鎖后,需要切換狀態(tài),而操作系統(tǒng)在實(shí)現(xiàn)線程的切換時(shí),需要從用戶態(tài)轉(zhuǎn)為核心態(tài),這是一個(gè)非常耗時(shí),非常重的操作。因此在之前,synchronized是一種重量級(jí)鎖。

JDK1.6之后對(duì)synchronized的優(yōu)化

現(xiàn)在的synchronized已經(jīng)沒(méi)有之前那么笨重了,在虛擬機(jī)層面,對(duì)synchronized做了較大的優(yōu)化,引入了自旋鎖、適應(yīng)性自旋鎖、鎖消除、鎖粗化,可以減少鎖操作的開(kāi)銷。

自旋鎖

有時(shí)候,獲取到鎖的線程執(zhí)行的操作耗時(shí)極短,為了這么點(diǎn)微不足道的時(shí)間,將接下來(lái)等待鎖的線程掛起非常的不值得。掛起線程的操作需要在核心態(tài)完成,從用戶態(tài)切換到核心態(tài),耗時(shí)比較嚴(yán)重。

因此現(xiàn)在增加這么一樣操作,讓等待鎖的線程執(zhí)行忙循環(huán)等待,不停地去嘗試獲取鎖,像一種自旋的操作,故稱之為自旋鎖。

如果之前線程占有鎖的時(shí)間極短,那么自旋鎖的性能將非常的好。但若是占有鎖的時(shí)間較長(zhǎng),那么自旋鎖將白白消耗CPU的資源,在自旋次數(shù)到了之后,將會(huì)被掛起。

在jdk1.4的時(shí)候,自旋鎖默認(rèn)關(guān)閉;jdk1.6之后,自旋鎖默認(rèn)開(kāi)啟,默認(rèn)自旋10次,當(dāng)然也可以使用PreBlockSpin來(lái)修改自旋次數(shù)。

自旋鎖的痛點(diǎn)在于:無(wú)法在不同場(chǎng)景中,確定出一個(gè)可靠的自旋次數(shù)。因此,衍生出來(lái)適應(yīng)性自旋鎖。

適應(yīng)性自旋鎖

在適應(yīng)性自旋鎖中,自旋的次數(shù)不再固定,一般由之前自旋的次數(shù)和鎖持有者的狀態(tài)決定。

如果在一個(gè)鎖對(duì)象上,之前的線程都能通過(guò)自旋來(lái)獲取到鎖,并且沒(méi)有超過(guò)自旋次數(shù),那么虛擬機(jī)認(rèn)為,通過(guò)自旋獲取到鎖的概率很大,下一次會(huì)增加自旋的次數(shù)。相反的,如果之前很少有線程通過(guò)自旋獲取到鎖,那么虛擬機(jī)會(huì)減少自旋的次數(shù),減少到一定次數(shù)后,甚至?xí)苯臃艞壸孕?jí)為重量級(jí)鎖。

可以看出,適應(yīng)性自旋鎖十分機(jī)智。

鎖消除

從字面意思上可以看出,這是一種直接去除鎖的方法,簡(jiǎn)單粗暴。

對(duì)于那些根本不可能存在鎖競(jìng)爭(zhēng)卻又包含鎖的情況,虛擬機(jī)會(huì)直接消除這個(gè)鎖,避免無(wú)意義的鎖請(qǐng)求。比如我在純單線程中對(duì)某個(gè)方法或者變量加鎖,或者調(diào)用內(nèi)部實(shí)現(xiàn)有鎖的對(duì)象(Vector、StringBuffer與HashTable等),虛擬機(jī)會(huì)直接消除毫無(wú)意義的加鎖。

鎖粗化

在上一文中【多線程】淺說(shuō)Synchronized,我們談到了synchronized的應(yīng)用-雙重檢驗(yàn)鎖的優(yōu)化過(guò)程,強(qiáng)調(diào)將加鎖的范圍盡量限制得小一些,直到存在鎖競(jìng)爭(zhēng)的實(shí)際區(qū)域才加鎖,這樣程序運(yùn)行更加高效。

但是,如果存在這樣的一種情況:反復(fù)的對(duì)同一個(gè)對(duì)象執(zhí)行加鎖解鎖的操作,也會(huì)導(dǎo)致CPU資源的過(guò)度消耗。

鎖粗化,就是將反復(fù)的加鎖操作粗化成一個(gè)范圍更大的鎖,這樣加鎖只有一次。

例如,在循環(huán)內(nèi)部,調(diào)用StringBuffer的append操作(關(guān)于StringBuffer,可以參考我的另外一篇文章【JAVA】String、StringBuilder、StringBuffer三者的區(qū)別),每次append都需要加鎖,虛擬機(jī)檢測(cè)到這種情況后,首先會(huì)對(duì)append脫鎖,然后進(jìn)行鎖粗化,將鎖的范圍擴(kuò)大到循環(huán)外部。

鎖的狀態(tài)

鎖的狀態(tài)有以下幾種:

  1. 無(wú)鎖狀態(tài)
  2. 偏向鎖狀態(tài)
  3. 輕量級(jí)鎖狀態(tài)
  4. 重量級(jí)鎖狀態(tài)

其中,無(wú)鎖狀態(tài)對(duì)應(yīng)于鎖消除,Monitor對(duì)應(yīng)于重量級(jí)鎖,也就是1.6之前的synchronized。

偏向鎖

偏向鎖的核心要義就體現(xiàn)在“偏”字上,這個(gè)鎖偏向第一個(gè)獲取到它的線程。

在大部分情況下,不存在激烈的鎖競(jìng)爭(zhēng),總是由同一個(gè)線程獲取到該鎖。那么為了減少同一個(gè)線程獲取鎖帶來(lái)的開(kāi)銷,就引入了偏向鎖。

如果一個(gè)線程不斷的獲取到了鎖,那么該鎖就進(jìn)入偏向鎖狀態(tài)。當(dāng)這個(gè)線程再次請(qǐng)求鎖時(shí),無(wú)需做任何同步操作,直接獲取到鎖。

當(dāng)然,偏向鎖適用于基本無(wú)鎖競(jìng)爭(zhēng)的情況,當(dāng)鎖競(jìng)爭(zhēng)激烈時(shí),偏向鎖就失去了作用,會(huì)升級(jí)為輕量級(jí)鎖。

輕量級(jí)鎖

在偏向鎖的狀態(tài)下,此時(shí)又出現(xiàn)了一個(gè)線程,與偏向線程競(jìng)爭(zhēng)該鎖,此時(shí)該鎖會(huì)升級(jí)為輕量級(jí)鎖。

舉個(gè)例子,比如創(chuàng)建一個(gè)線程1執(zhí)行同步print()方法打印奇數(shù),這時(shí)候的鎖狀態(tài)為偏向鎖。此時(shí),再創(chuàng)建一個(gè)線程2同樣執(zhí)行同步print()方法打印偶數(shù),偏向鎖就會(huì)升級(jí)為輕量級(jí)鎖。線程1打印某個(gè)奇數(shù)時(shí),線程2并沒(méi)有被掛起,而是處于一種自旋狀態(tài),這種自旋效率很高。可是,當(dāng)我再創(chuàng)建100個(gè)線程時(shí),同樣執(zhí)行同步print()方法,自旋的效率將會(huì)變得十分低下,此時(shí)輕量級(jí)鎖會(huì)升級(jí)為重量級(jí)鎖,即使用Monitor來(lái)進(jìn)行同步。

鎖的升級(jí)

無(wú)鎖、偏向鎖、輕量級(jí)鎖與重量級(jí)鎖,會(huì)隨著鎖競(jìng)爭(zhēng)的升級(jí)而升級(jí)。

從一開(kāi)始的偏向鎖,產(chǎn)生鎖競(jìng)爭(zhēng)后,升級(jí)為輕量級(jí)鎖,自旋失敗后,升級(jí)為重量級(jí)鎖,一般來(lái)說(shuō),鎖的升級(jí)是單向的。

 

責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2023-09-01 08:59:57

2021-06-11 06:54:35

DPDK優(yōu)化HugeTLB

2024-02-29 18:06:39

HTTP性能優(yōu)化

2022-07-04 08:01:01

鎖優(yōu)化Java虛擬機(jī)

2025-03-26 00:55:00

2024-09-03 08:09:00

2020-12-31 05:33:34

軟件性能優(yōu)化

2021-11-10 18:52:42

SQL技巧優(yōu)化

2020-11-12 08:32:14

Vue3模板優(yōu)化

2021-08-03 07:40:46

Synchronize鎖膨脹性能

2020-11-24 11:16:06

JavaScript

2021-11-18 08:20:22

接口索引SQL

2022-03-11 10:23:02

React性能優(yōu)化

2023-07-13 11:24:14

SQL優(yōu)化賦值

2023-07-31 07:48:43

Java內(nèi)存虛擬機(jī)

2023-05-26 18:52:55

2023-12-02 20:41:32

內(nèi)存kube

2021-09-03 23:01:58

CSS 技巧代碼重構(gòu)

2024-11-22 00:09:15

2023-03-26 22:42:02

SQL關(guān)聯(lián)索引
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)