作用:能夠保證在同一時刻最多只有一個線程執(zhí)行該段代碼喻犁,以達到保證并發(fā)安全的效果汽纤。
地位:java關鍵字上岗,是最基本的互斥同步手段,并發(fā)編程中必學
不使用并發(fā):例如蕴坪,我們做一個簡單的累加肴掷,累加10萬次,利用兩個線程背传,那么應該一共是累加到20萬呆瞻,
但是實際結果我們會發(fā)現(xiàn),根本不會到20萬径玖,基本到是14萬這種的痴脾,這就是沒有使用Synchronized導致的后果。在每次累加的時候梳星,一次累加包含讀取值赞赖,加一滚朵,寫入內存三個操作。例如前域,線程a在執(zhí)行加一的時候辕近,在讀取值5,然后加一了變成6匿垄,在沒有寫入寫存的時候移宅,線程b就執(zhí)行了讀取值,這個時候讀取的也是5椿疗,然后加一變成6寫入內存漏峰,這也就是為什么兩個線程在累加的時候,最終的結果會小于20萬的原因了届榄。這種情況浅乔,也就是我們通常所說的線程不安全,因為沒有加鎖痒蓬。
方法鎖:默認鎖對象為this當前實例對象童擎。
同步代碼塊鎖:自己制定鎖對象。
類鎖:Synchronized修飾的靜態(tài)方法或制指定鎖為class對象攻晒。
在類中加入Synchronized顾复,可以保證程序是串行執(zhí)行的,如果沒有加鲁捏,那么代碼塊就會是并行執(zhí)行芯砸,也就是會同時執(zhí)行的。Synchronized(this){};最關鍵的就是鎖的對象的選取给梅,這里選取的是this假丧,當前對象。對于需要鎖住的對象动羽,要根據具體的業(yè)務邏輯來選取包帚。
多線程訪問同步的七種情況:
1:兩個線程同時訪問一個對象的同步方法(串行,同一個實例运吓,同一把鎖渴邦,需要等待)
2:兩個線程同時訪問兩個對象的同步方法(并行,鎖的是不同對象)
3:兩個線程訪問的是Synchronized的靜態(tài)方法(串行拘哨,只要是靜態(tài)的谋梭,鎖的對象就是同一把)
4:同時訪問同步方法和非同步方法(同時執(zhí)行,同時結束倦青,并行)
5:訪問同一個對象的不相同的普通同步方法(非靜態(tài))(一個先執(zhí)行結束瓮床,后一個再執(zhí)行結束,串行)
6:同時訪問靜態(tài)Synchronized方法和非靜態(tài)Synchronized方法(同時開始,同時結束隘庄。鎖指定的所對象不是同一個鎖)
7:方法拋異常后踢步,會釋放鎖(第一個線程異常,但是第二個線程可以運行峭沦,則說明鎖釋放了)
總結:
1.一把鎖只能同時被一個線程獲取贾虽,沒有拿到鎖的線程必須等待
2.每個實例都對應自己的一把鎖逃糟,不同實例之間互不影響吼鱼,鎖對象是*.class以及synchronized修飾的static方法的時候,所有對象共用同一把類鎖
3.無論是方法正常執(zhí)行或者方法拋出異常绰咽,都會釋放鎖