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