@Java | Thread synchronized - [ 線程同步鎖 基本使用]

對實現了Runnable或者Callable接口類,可以通過多線程執行同一實例的runcall方法,那么對于同一實例中的局部變量(非方法變量)就會有多個線程進行更改或讀取,這就會導致數據不一致,synchronized(關鍵字)可以解決多線程共享數據同步的問題

synchronized使用說明

作用范圍

synchronized是Java中的關鍵字,是一種同步鎖。它修飾的對象有以下幾種:
  1. 修飾一個代碼塊:被修飾的代碼塊稱為同步語句塊,其作用的范圍是大括號{}括起來的代碼,作用的對象是調用這個代碼塊的對象
  2. 修飾一個非靜態方法:被修飾的方法稱為同步方法,其作用的范圍是整個方法,作用的對象是調用這個方法的對象
  3. 修改一個靜態的方法:其作用的范圍是整個靜態方法,作用的對象是這個類的所有對象
  4. 修改一個類:其作用的范圍是synchronized后面括號括起來的部分,作用主的對象是這個類的所有對象
高能提示:
No1 > synchronized修飾的非靜態方法:如果一個對象多個synchronized方法,只要一個線程訪問了其中的一個synchronized方法,則這個線程所屬對象其它線程不能同時訪問這個對象任何一個synchronized方法
No2 > synchronized關鍵字是不能繼承的:基類的方法synchronized function(){}在繼承類中并不自動是synchronized function(){},而是變成了function(){}。繼承類需要你顯式的指定它的某個方法為synchronized方法,可以通過子類調用父類的同步方法來實現同步
No3 > 針對synchronized修飾代碼塊和非靜態方法,本質上鎖的是代碼塊或非靜態方法對應的對象代碼塊是synchronized標注的變量,非靜態方法是所在類對應的實例),如果是不同的對象是可以同時訪問的
No4 > 實現同步是要很大的系統開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制
No5 > 每個對象只有一個鎖(lock)與之相關聯
No6 > 在定義接口方法時不能使用synchronized關鍵字
No7 > 構造方法不能使用synchronized關鍵字,但可以使用synchronized代碼塊來進行同步

1. 修飾一個代碼塊

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作用于一個類時,是給這個類加鎖,類的所有對象用的是同一把鎖

總結

  1. 線程同步的目的是為了保護多個線程反問一個資源時對資源的破壞。
  2. 線程同步方法是通過鎖來實現,每個對象都有切僅有一個鎖,這個鎖與一個特定的對象關聯,線程一旦獲取了對象鎖,其他訪問該對象的線程就無法再訪問該對象的其他非同步方法
  3. 對于靜態同步方法,鎖是針對這個類的,鎖對象是該類的Class對象。靜態和非靜態方法的鎖互不干預。一個線程獲得鎖,當在一個同步方法中訪問另外對象上的同步方法時,會獲取這兩個對象鎖。
  4. 對于同步,要時刻清醒在哪個對象上同步,這是關鍵。
  5. 編寫線程安全的類,需要時刻注意對多個線程競爭訪問資源的邏輯和安全做出正確的判斷,對"原子"操作做出分析,并保證原子操作期間別的線程無法訪問競爭資源。
  6. 當多個線程等待一個對象鎖時,沒有獲取到鎖的線程將發生阻塞。
  7. 死鎖是線程間相互等待鎖鎖造成的,在實際中發生的概率非常的小,一旦程序發生死鎖,程序將死掉

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/451677.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/451677.shtml
英文地址,請注明出處:http://en.pswp.cn/news/451677.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: ORA-00911: 無效字符

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 1. 報錯: ### Cause: java.sql.SQLSyntaxErrorException: ORA-00911: 無效字符; bad SQL grammar []; nested exception is …

開源代碼的使用 二次開發

開源開發,就我的理解,有三種。 1、當作底層基礎,使用。例如大家使用mysql就算。有人會認為我說錯了。但我認為,開發不代表就是要同一個語言,甚至修改代碼。例如我們使用動態庫,原先的動態庫是什么寫的并不重…

Java Application和Java Applet

Java Applet和Java Application 主要區別: (1)運行方式不同。Java Applet程序不能單獨運行,它必須依附于一個用HTML語言編寫的網頁并嵌入其中,通過與Java兼容的瀏覽器來控制執行。 Java Application是完整的程序&a…

激活prompt

1.下載SQLPrompt 2. 斷網, 打開注冊機,拷貝驗證碼 2. 點擊activate, 拷貝代碼 轉載于:https://www.cnblogs.com/zxhome/p/9459415.html

Map 四種獲取 key 和 value 值的方法,以及對 map 中的元素排序

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。1. 獲取map的值主要有四種方法,分為兩類: 調用 map.keySet() 方法來獲取 key 和 value 的值; 通…

三、【Map】

主要內容 Map集合 教學目標 能夠說出Map集合特點 使用Map集合添加方法保存數據 使用”鍵找值”的方式遍歷Map集合 使用”鍵值對”的方式遍歷Map集合 能夠使用HashMap存儲自定義鍵值對的數據 能夠使用HashMap編寫斗地主洗牌發牌案例 第一章 Map集合 1.1 概述 現實生活中&am…

五種開源協議的比較(BSD,Apache,GPL,LGPL,MIT) – 整理

當Adobe、Microsoft、Sun等一系列巨頭開始表現出對”開源”的青睞時,”開源”的時代即將到來! 最初來自:sinoprise.com/read.php?tid-662-page-e-fpage-1.html(遺憾的是這個鏈接已經打不開了),我基本未改…

[轉]自然語言處理中的Attention Model:是什么及為什么

自然語言處理中的Attention Model:是什么及為什么 https://blog.csdn.net/malefactor/article/details/50550211/* 版權聲明:可以任意轉載,轉載時請標明文章原始出處和作者信息 .*/ author: 張俊林 要是關注深度學習在自然語言處理方面…

關西旅游地名讀法學習

京都個人旅行ための自己勉強 京都篇 伏見稲荷大社「ふしみいなりだいしゃ」 京都府京都市伏見區深草にある神社。舊稱は稲荷神社 全國に約三萬社あるといわれる稲荷神社の総本社である。 初詣では近畿地方の社寺で最多の參拝者を集める。(日本第4位)。 清水寺 「き…

jsp頁面c標簽循環map , c:foreach 循環map

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 <c:forEach items"${customerMap}" var"item"> ${item.code} ${item.name} </c:forEach> map…

JSP上下文

上下文即ServletContext,是一個全局的儲存信息的空間&#xff0c;服務器啟動&#xff0c;其就存在&#xff0c;服務器關閉&#xff0c;其才釋放。所有用戶共用一個ServletContext。所以&#xff0c;為了節省空間&#xff0c;提高效率&#xff0c;ServletContext中&#xff0c;要…

python ERROR: Cannot uninstall ‘certifi‘.

解決方法 pip install xxx --ignore-installed certifigithub參考鏈接

HDU - 6383 百度之星2018初賽B 1004 p1m2(二分答案)

p1m2 Accepts: 1003Submissions: 4595Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 131072/131072 K (Java/Others)Problem Description度度熊很喜歡數組&#xff01;&#xff01;我們稱一個整數數組為穩定的&#xff0c;若且唯若其同時符合以下兩個條件&#xff1a…

整合營銷推廣該如何做?

思維方式太重要了&#xff0c;如果你認為你的產品只是推廣出去就好&#xff0c;推廣就能有銷量的話&#xff0c;那你大錯特錯了。本文主要的分享給創業者和企業老板的&#xff0c;如果你想做好網絡營銷推廣&#xff0c;這篇文章不看是你的損失。 首先記住&#xff1a;推廣不等于…

如何使用git命令行上傳項目到github

參考文獻&#xff1a; 如何使用git命令行上傳項目到github 感謝樓主分享&#xff01;

優質的程序員需為代碼效率而嘔心瀝血

一個好的程序員必須要為自己寫出來的代碼執行效率負責。并非僅僅實現了功能代碼就完事了。很多工作一兩年的程序員都還僅是處于實現功能代碼為榮的階段&#xff0c;不會過多去思考如何提高代碼的執行效率。有的人認為是自己的能力就這樣&#xff0c;沒有多余的能力去思考這些額…

用gson得JSON,數值變為double類型 ,去掉double值中的小數位(3.0改為3)

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 項目中有個接口的數據是從緩存中讀取再組成JSON 格式返出&#xff0c;原本緩存中數據是這樣的&#xff1a; 用Gson 組成JSON 后&…

Python中的join()函數的用法

函數&#xff1a;string.join()Python中有join()和os.path.join()兩個函數&#xff0c;具體作用如下&#xff1a; join()&#xff1a; 連接字符串數組。將字符串、元組、列表中的元素以指定的字符(分隔符)連接生成一個新的字符串 os.path.join()&#xff1a; 將多個路…