在并發(fā)編程中,多線(xiàn)程同時(shí)并發(fā)訪(fǎng)問(wèn)的資源叫做臨界資源,當(dāng)多個(gè)線(xiàn)程同時(shí)訪(fǎng)問(wèn)對(duì)象并要求操作相同資源時(shí),分割了原子操作就有可能出現(xiàn)數(shù)據(jù)的不一致或數(shù)據(jù)不完整的情況,為避免這種情況的發(fā)生,我們會(huì)采取同步機(jī)制,以確保在某一時(shí)刻,方法內(nèi)只允許有一個(gè)線(xiàn)程。
采用 synchronized 修飾符實(shí)現(xiàn)的同步機(jī)制叫做互斥鎖機(jī)制,它所獲得的鎖叫做互斥鎖。每個(gè)對(duì)象都有一個(gè) monitor (鎖標(biāo)記),當(dāng)線(xiàn)程擁有這個(gè)鎖標(biāo)記時(shí)才能訪(fǎng)問(wèn)這個(gè)資源,沒(méi)有鎖標(biāo)記便進(jìn)入鎖池。任何一個(gè)對(duì)象系統(tǒng)都會(huì)為其創(chuàng)建一個(gè)互斥鎖,這個(gè)鎖是為了分配給線(xiàn)程的,防止打斷原子操作。每個(gè)對(duì)象的鎖只能分配給一個(gè)線(xiàn)程,因此叫做互斥鎖。
這里就使用同步機(jī)制獲取互斥鎖的情況,進(jìn)行幾點(diǎn)說(shuō)明:
如果同一個(gè)方法內(nèi)同時(shí)有兩個(gè)或更多線(xiàn)程,則每個(gè)線(xiàn)程有自己的局部變量拷貝。
類(lèi)的每個(gè)實(shí)例都有自己的對(duì)象級(jí)別鎖。當(dāng)一個(gè)線(xiàn)程訪(fǎng)問(wèn)實(shí)例對(duì)象中的 synchronized 同步代碼塊或同步方法時(shí),該線(xiàn)程便獲取了該實(shí)例的對(duì)象級(jí)別鎖,其他線(xiàn)程這時(shí)如果要訪(fǎng)問(wèn) synchronized 同步代碼塊或同步方法,便需要阻塞等待,直到前面的線(xiàn)程從同步代碼塊或方法中退出,釋放掉了該對(duì)象級(jí)別鎖。
訪(fǎng)問(wèn)同一個(gè)類(lèi)的不同實(shí)例對(duì)象中的同步代碼塊,不存在阻塞等待獲取對(duì)象鎖的問(wèn)題,因?yàn)樗鼈儷@取的是各自實(shí)例的對(duì)象級(jí)別鎖,相互之間沒(méi)有影響。
持有一個(gè)對(duì)象級(jí)別鎖不會(huì)阻止該線(xiàn)程被交換出來(lái),也不會(huì)阻塞其他線(xiàn)程訪(fǎng)問(wèn)同一示例對(duì)象中的非 synchronized 代碼。當(dāng)一個(gè)線(xiàn)程 A 持有一個(gè)對(duì)象級(jí)別鎖(即進(jìn)入了 synchronized 修飾的代碼塊或方法中)時(shí),線(xiàn)程也有可能被交換出去,此時(shí)線(xiàn)程 B 有可能獲取執(zhí)行該對(duì)象中代碼的時(shí)間,但它只能執(zhí)行非同步代碼(沒(méi)有用 synchronized 修飾),當(dāng)執(zhí)行到同步代碼時(shí),便會(huì)被阻塞,此時(shí)可能線(xiàn)程規(guī)劃器又讓 A 線(xiàn)程運(yùn)行,A 線(xiàn)程繼續(xù)持有對(duì)象級(jí)別鎖,當(dāng) A 線(xiàn)程退出同步代碼時(shí)(即釋放了對(duì)象級(jí)別鎖),如果 B 線(xiàn)程此時(shí)再運(yùn)行,便會(huì)獲得該對(duì)象級(jí)別鎖,從而執(zhí)行 synchronized 中的代碼。
持有對(duì)象級(jí)別鎖的線(xiàn)程會(huì)讓其他線(xiàn)程阻塞在所有的 synchronized 代碼外。例如,在一個(gè)類(lèi)中有三個(gè)synchronized 方法 a,b,c,當(dāng)線(xiàn)程 A 正在執(zhí)行一個(gè)實(shí)例對(duì)象 M 中的方法 a 時(shí),它便獲得了該對(duì)象級(jí)別鎖,那么其他的線(xiàn)程在執(zhí)行同一實(shí)例對(duì)象(即對(duì)象 M)中的代碼時(shí),便會(huì)在所有的 synchronized 方法處阻塞,即在方法 a,b,c 處都要被阻塞,等線(xiàn)程 A 釋放掉對(duì)象級(jí)別鎖時(shí),其他的線(xiàn)程才可以去執(zhí)行方法 a,b 或者 c 中的代碼,從而獲得該對(duì)象級(jí)別鎖。
使用 synchronized(obj)同步語(yǔ)句塊,可以獲取指定對(duì)象上的對(duì)象級(jí)別鎖。obj 為對(duì)象的引用,如果獲取了 obj 對(duì)象上的對(duì)象級(jí)別鎖,在并發(fā)訪(fǎng)問(wèn) obj 對(duì)象時(shí)時(shí),便會(huì)在其 synchronized 代碼處阻塞等待,直到獲取到該 obj對(duì)象的對(duì)象級(jí)別鎖。當(dāng) obj 為 this 時(shí),便是獲取當(dāng)前對(duì)象的對(duì)象級(jí)別鎖。
類(lèi)級(jí)別鎖被特定類(lèi)的所有示例共享,它用于控制對(duì) static 成員變量以及 static 方法的并發(fā)訪(fǎng)問(wèn)。具體用法與對(duì)象級(jí)別鎖相似。