摘要:線程同步方法是通過(guò)鎖來(lái)實(shí)現(xiàn),每個(gè)對(duì)象都有切僅有一個(gè)鎖,這個(gè)鎖與一個(gè)特定的對(duì)象關(guān)聯(lián),線程一旦獲取了對(duì)象鎖,其他訪問(wèn)該對(duì)象的線程就無(wú)法再訪問(wèn)該對(duì)象的其他非同步方法對(duì)于靜態(tài)同步方法,鎖是針對(duì)這個(gè)類的,鎖對(duì)象是該類的對(duì)象。
對(duì)實(shí)現(xiàn)了Runnable或者Callable接口類,可以通過(guò)多線程執(zhí)行同一實(shí)例的run或call方法,那么對(duì)于同一實(shí)例中的局部變量(非方法變量)就會(huì)有多個(gè)線程進(jìn)行更改或讀取,這就會(huì)導(dǎo)致數(shù)據(jù)不一致,synchronized(關(guān)鍵字)可以解決多線程共享數(shù)據(jù)同步的問(wèn)題synchronized使用說(shuō)明 作用范圍
synchronized是Java中的關(guān)鍵字,是一種同步鎖。它修飾的對(duì)象有以下幾種:
修飾一個(gè)代碼塊:被修飾的代碼塊稱為同步語(yǔ)句塊,其作用的范圍是大括號(hào){}括起來(lái)的代碼,作用的對(duì)象是調(diào)用這個(gè)代碼塊的對(duì)象
修飾一個(gè)非靜態(tài)方法:被修飾的方法稱為同步方法,其作用的范圍是整個(gè)方法,作用的對(duì)象是調(diào)用這個(gè)方法的對(duì)象
修改一個(gè)靜態(tài)的方法:其作用的范圍是整個(gè)靜態(tài)方法,作用的對(duì)象是這個(gè)類的所有對(duì)象
修改一個(gè)類:其作用的范圍是synchronized后面括號(hào)括起來(lái)的部分,作用主的對(duì)象是這個(gè)類的所有對(duì)象
高能提示:1. 修飾一個(gè)代碼塊
No1 > synchronized修飾的非靜態(tài)方法:如果一個(gè)對(duì)象有多個(gè)synchronized方法,只要一個(gè)線程訪問(wèn)了其中的一個(gè)synchronized方法,則這個(gè)線程所屬對(duì)象的其它線程不能同時(shí)訪問(wèn)這個(gè)對(duì)象中任何一個(gè)synchronized方法
No2 > synchronized關(guān)鍵字是不能繼承的:基類的方法synchronized function(){}在繼承類中并不自動(dòng)是synchronized function(){},而是變成了function(){}。繼承類需要你顯式的指定它的某個(gè)方法為synchronized方法,可以通過(guò)子類調(diào)用父類的同步方法來(lái)實(shí)現(xiàn)同步
No3 > 針對(duì)synchronized修飾代碼塊和非靜態(tài)方法,本質(zhì)上鎖的是代碼塊或非靜態(tài)方法對(duì)應(yīng)的對(duì)象(代碼塊是synchronized標(biāo)注的變量,非靜態(tài)方法是所在類對(duì)應(yīng)的實(shí)例),如果是不同的對(duì)象是可以同時(shí)訪問(wèn)的
No4 > 實(shí)現(xiàn)同步是要很大的系統(tǒng)開(kāi)銷作為代價(jià)的,甚至可能造成死鎖,所以盡量避免無(wú)謂的同步控制
No5 > 每個(gè)對(duì)象只有一個(gè)鎖(lock)與之相關(guān)聯(lián)
No6 > 在定義接口方法時(shí)不能使用synchronized關(guān)鍵字
No7 > 構(gòu)造方法不能使用synchronized關(guān)鍵字,但可以使用synchronized代碼塊來(lái)進(jìn)行同步
public void syncCode(Object o) { synchronized (o) {// 同步代碼塊} }
上面的鎖就是o這個(gè)對(duì)象,當(dāng)然多個(gè)線程同步需要保證o這個(gè)對(duì)象是同一個(gè),這是有明確的對(duì)象作為鎖的情況,如果只是想單純的讓某一段代碼同步,并沒(méi)有明確的對(duì)象作為鎖,可以創(chuàng)建一個(gè)特殊的instance變量來(lái)充當(dāng)鎖
synchronized(o)修飾的代碼塊,其中o可以取值一個(gè)對(duì)象或者一個(gè)變量或者this亦或者Clz.class
public class Sync implements Runnable { private byte[] lock = new byte[0]; public void syncCode() { synchronized (lock) {// 同步代碼塊} } public void run .... }
注:零長(zhǎng)度的byte數(shù)組對(duì)象創(chuàng)建起來(lái)將比任何對(duì)象都經(jīng)濟(jì),查看編譯后的字節(jié)碼,生成零長(zhǎng)度的byte[]對(duì)象只需3條操作碼,而Object lock = new Object()則需要7行操作碼2. 修飾一個(gè)非靜態(tài)方法
public synchronized void method() {// .....}
此時(shí)鎖的是調(diào)用這個(gè)同步方法的對(duì)象3. 修飾一個(gè)靜態(tài)方法
public synchronized static void method() {// .....}
synchronized修飾的靜態(tài)方法鎖定的是這個(gè)類的所有對(duì)象4. 修飾類
public class Sync implements Runnable { public void syncCode() { synchronized (Sync.class) {// 同步代碼塊} } public void run .... }
和作用于靜態(tài)方法一樣,synchronized作用于一個(gè)類時(shí),是給這個(gè)類加鎖,類的所有對(duì)象用的是同一把鎖總結(jié)
線程同步的目的是為了保護(hù)多個(gè)線程反問(wèn)一個(gè)資源時(shí)對(duì)資源的破壞。
線程同步方法是通過(guò)鎖來(lái)實(shí)現(xiàn),每個(gè)對(duì)象都有切僅有一個(gè)鎖,這個(gè)鎖與一個(gè)特定的對(duì)象關(guān)聯(lián),線程一旦獲取了對(duì)象鎖,其他訪問(wèn)該對(duì)象的線程就無(wú)法再訪問(wèn)該對(duì)象的其他非同步方法
對(duì)于靜態(tài)同步方法,鎖是針對(duì)這個(gè)類的,鎖對(duì)象是該類的Class對(duì)象。靜態(tài)和非靜態(tài)方法的鎖互不干預(yù)。一個(gè)線程獲得鎖,當(dāng)在一個(gè)同步方法中訪問(wèn)另外對(duì)象上的同步方法時(shí),會(huì)獲取這兩個(gè)對(duì)象鎖。
對(duì)于同步,要時(shí)刻清醒在哪個(gè)對(duì)象上同步,這是關(guān)鍵。
編寫線程安全的類,需要時(shí)刻注意對(duì)多個(gè)線程競(jìng)爭(zhēng)訪問(wèn)資源的邏輯和安全做出正確的判斷,對(duì)"原子"操作做出分析,并保證原子操作期間別的線程無(wú)法訪問(wèn)競(jìng)爭(zhēng)資源。
當(dāng)多個(gè)線程等待一個(gè)對(duì)象鎖時(shí),沒(méi)有獲取到鎖的線程將發(fā)生阻塞。
死鎖是線程間相互等待鎖鎖造成的,在實(shí)際中發(fā)生的概率非常的小,一旦程序發(fā)生死鎖,程序?qū)⑺赖?/p>
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/69513.html
摘要:線程線程是進(jìn)程中的一個(gè)實(shí)體,作為系統(tǒng)調(diào)度和分派的基本單位。下的線程看作輕量級(jí)進(jìn)程。因此,使用的目的是讓相同優(yōu)先級(jí)的線程之間能適當(dāng)?shù)妮嗈D(zhuǎn)執(zhí)行。需要注意的是,是線程自己從內(nèi)部拋出的,并不是方法拋出的。 本文及后續(xù)相關(guān)文章梳理一下關(guān)于多線程和同步鎖的知識(shí),平時(shí)只是應(yīng)用層面的了解,由于最近面試總是問(wèn)一些原理性的知識(shí),雖說(shuō)比較反感這種理論派,但是為了生計(jì)也必須掌握一番。(PS:并不是說(shuō)掌握原理不...
摘要:死亡線程方法執(zhí)行結(jié)束,或者因異常退出了方法,則該線程結(jié)束生命周期。死亡的線程不可再次復(fù)生。直到當(dāng)前的線程放棄此對(duì)象上的鎖定,才能繼續(xù)執(zhí)行被喚醒的線程。枚舉程序中的線程。強(qiáng)迫一個(gè)線程等待。通知一個(gè)線程繼續(xù)運(yùn)行。 一. 線程狀態(tài)轉(zhuǎn)換圖 showImg(https://segmentfault.com/img/bV38ef?w=968&h=680); 線程間的狀態(tài)轉(zhuǎn)換說(shuō)明: 新建(new)...
摘要:線程啟動(dòng)規(guī)則對(duì)象的方法先行發(fā)生于此線程的每一個(gè)動(dòng)作。所以局部變量是不被多個(gè)線程所共享的,也就不會(huì)出現(xiàn)并發(fā)問(wèn)題。通過(guò)獲取到數(shù)據(jù),放入當(dāng)前線程處理完之后將當(dāng)前線程中的信息移除。主線程必須在啟動(dòng)其他線程后立即調(diào)用方法。 一、線程安全性 定義:當(dāng)多個(gè)線程訪問(wèn)某個(gè)類時(shí),不管運(yùn)行時(shí)環(huán)境采用何種調(diào)度方式,或者這些線程將如何交替執(zhí)行,并且在主調(diào)代碼中不需要任何額外的同步或協(xié)同,這個(gè)類都能表現(xiàn)出正確的行...
摘要:當(dāng)一個(gè)線程持有重量級(jí)鎖時(shí),另外一個(gè)線程就會(huì)被直接踢到同步隊(duì)列中等待。 java代碼先編譯成字節(jié)碼,字節(jié)碼最后編譯成cpu指令,因此Java的多線程實(shí)現(xiàn)最終依賴于jvm和cpu的實(shí)現(xiàn) synchronized和volatile 我們先來(lái)討論一下volatile關(guān)鍵字的作用以及實(shí)現(xiàn)機(jī)制,每個(gè)線程看到的用volatile修飾的變量的值都是最新的,更深入的解釋就涉及到Java的內(nèi)存模型了,我們...
閱讀 1282·2021-11-24 11:16
閱讀 3491·2021-11-15 11:38
閱讀 2020·2021-10-20 13:47
閱讀 628·2021-09-29 09:35
閱讀 2262·2021-09-22 15:17
閱讀 1087·2021-09-07 09:59
閱讀 3441·2019-08-30 13:21
閱讀 2959·2019-08-30 12:47