本篇文章為大家帶來了關於java的相關知識,其中主要介紹了關於synchronized關鍵字的相關問題,包括了使用同步方法、使用同步語句或區塊以及什麼是同步、為什麼需要同步的相關內容,下面一起來看一下,希望對大家有幫助。
推薦學習:《java影片教學》
在平時開發中,synchronized關鍵字常遇到,你知道synchronized怎麼用嗎?本文跟大家介紹一下。
我們有兩種方法可以使用同步:
- 使用同步方法
- 使用同步語句或區塊
使用同步方法
要讓方法同步,只需將synchronized關鍵字新增至其聲明:
public class SynchronizedDemo { private int i = 0; public synchronized void add() { i++; } public synchronized void del() { i--; } public synchronized int getValue() { return i; } }
如上程式碼顯示,一共有三個同步方法:
- add()
- del()
- getValue()
每個方法同一個物件同一時刻只會被調用一次,例如一個執行緒在呼叫add()時,其他執行緒都會被阻塞,直到第一個執行緒處理完add()方法。
使用同步語句或區塊
public void del(int value){ synchronized(this){ this.i -= value; } }
如上程式碼,synchronized加在了一個{}程式碼前,這個就代表是一個同步程式碼區塊。
以上就是synchronized關鍵字兩種使用方法,以下我們來簡單的介紹一下同步相關的概念。
什麼是同步?
同步是一個控制多個執行緒存取任何共享資源的進程,可以避免不一致的結果。使用同步的主要目的是避免執行緒的不一致行為,防止執行緒幹擾。
在java中可以使用synchronized 關鍵字來實現同步的效果,synchronized只能應用於方法和區塊,不能應用於變數和類別。
為啥需要同步?
首先我們來看一段程式碼:
public class SynchronizedDemo { int i; public void increment() { i++; } public static void main(String[] args) { SynchronizedDemo synchronizedDemo = new SynchronizedDemo(); synchronizedDemo.increment(); System.out.println("计算值为:" + synchronizedDemo.i); } }
每當呼叫increment()方法時計算值都會加1:
調用2次就會加2,呼叫3次就會加3,呼叫4次就會加4:
public class SynchronizedDemo { int i; public void increment() { i++; } public static void main(String[] args) { SynchronizedDemo synchronizedDemo = new SynchronizedDemo(); synchronizedDemo.increment(); synchronizedDemo.increment(); synchronizedDemo.increment(); synchronizedDemo.increment(); System.out.println("计算值为:" + synchronizedDemo.i); } }
現在我們擴充一下上面的例子,建立一個線程去呼叫10次increment()方法:
public class SynchronizedDemo { int i; public void increment() { i++; } public static void main(String[] args) { SynchronizedDemo synchronizedDemo = new SynchronizedDemo(); Thread thread = new Thread(() -> { for (int i = 1; i <= 10; i++) { synchronizedDemo.increment(); } }); thread.start(); try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("计算值为:" + synchronizedDemo.i); } }
此時計算的結果正如我們預期的那樣,結果為10.
public class SynchronizedDemo { int i; public void increment() { i++; } public static void main(String[] args) { SynchronizedDemo synchronizedDemo = new SynchronizedDemo(); Thread thread1 = new Thread(() -> { for (int i = 1; i <= 1000; i++) { synchronizedDemo.increment(); } }); Thread thread2 = new Thread(() -> { for (int i = 1; i <= 1000; i++) { synchronizedDemo.increment(); } }); thread1.start(); thread2.start(); try { thread1.join(); thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("计算值为:" + synchronizedDemo.i); } }如上程式碼,我們建立了兩個執行緒thread1 和thread2,每個執行緒呼叫1000次increment(),理論上最終列印的值應該是
2000#,因為thread1呼叫increment ()1000次後值會變成1000,thread2呼叫increment()1000次後值會變成2000.
我們執行一下,看看結果:
public class SynchronizedDemo { int i; public synchronized void increment() { i++; } public static void main(String[] args) { SynchronizedDemo synchronizedDemo = new SynchronizedDemo(); Thread thread1 = new Thread(() -> { for (int i = 1; i <= 1000; i++) { synchronizedDemo.increment(); } }); Thread thread2 = new Thread(() -> { for (int i = 1; i <= 1000; i++) { synchronizedDemo.increment(); } }); thread1.start(); thread2.start(); try { thread1.join(); thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("计算值为:" + synchronizedDemo.i); } }這個時候我們再執行一下:
public class SynchronizedDemo { int i; public synchronized void increment() { i++; } public static void main(String[] args) { SynchronizedDemo synchronizedDemo = new SynchronizedDemo(); Thread thread1 = new Thread(() -> { for (int i = 1; i <= 10000; i++) { synchronizedDemo.increment(); } }); Thread thread2 = new Thread(() -> { for (int i = 1; i <= 10000; i++) { synchronizedDemo.increment(); } }); thread1.start(); thread2.start(); try { thread1.join(); thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("计算值为:" + synchronizedDemo.i); } }###執行結果為:###############可以看出,一個小小的synchronized竟然那麼簡單的就解決了這個問題。 ###
這個背後的原理就是線程1執行increment()方法時,因為有synchronized,所以會自動將此方法加鎖,而此時只有線程1擁有這把鎖,其他線程只能等待,直到線程1釋放這把鎖,線程2才能參與呼叫。
同理,當線程2去調用increment()時,線程2拿到鎖,線程1進入等待,直到線程2釋放鎖,就這樣,直到計算完畢,在此過程中,不會出現計算錯誤的情況。
總結
- synchronized 關鍵字是使區塊或方法同步的唯一方法。
- synchronized 關鍵字提供了鎖定的特性,它確保執行緒之間不會出現競爭條件。被鎖定後,執行緒只能從主記憶體讀取數據,讀取資料後,它會刷新寫入操作,然後才能釋放鎖定。
- synchronized 關鍵字也有助於避免程式語句的重新排序。
推薦學習:《java影片教學》
以上是一個例子看懂Java中synchronized關鍵字到底怎麼用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Javaremainsagoodlanguageduetoitscontinuousevolutionandrobustecosystem.1)Lambdaexpressionsenhancecodereadabilityandenablefunctionalprogramming.2)Streamsallowforefficientdataprocessing,particularlywithlargedatasets.3)ThemodularsystemintroducedinJava9im

Javaisgreatduetoitsplatformindependence,robustOOPsupport,extensivelibraries,andstrongcommunity.1)PlatformindependenceviaJVMallowscodetorunonvariousplatforms.2)OOPfeatureslikeencapsulation,inheritance,andpolymorphismenablemodularandscalablecode.3)Rich

Java的五大特色是多態性、Lambda表達式、StreamsAPI、泛型和異常處理。 1.多態性讓不同類的對象可以作為共同基類的對象使用。 2.Lambda表達式使代碼更簡潔,特別適合處理集合和流。 3.StreamsAPI高效處理大數據集,支持聲明式操作。 4.泛型提供類型安全和重用性,編譯時捕獲類型錯誤。 5.異常處理幫助優雅處理錯誤,編寫可靠軟件。

java'stopfeatureSnificallyenhanceItsperformanCandScalability.1)對象 - 方向clincipleslike-polymormormormormormormormormormormormorableableflexibleandscalablecode.2)garbageCollectionAutectionAutoctionAutoctionAutoctionAutoctionAutoctionAutoMenateMememorymanateMmanateMmanateMmanagementButCancausElatemention.3)

JVM的核心組件包括ClassLoader、RuntimeDataArea和ExecutionEngine。 1)ClassLoader負責加載、鏈接和初始化類和接口。 2)RuntimeDataArea包含MethodArea、Heap、Stack、PCRegister和NativeMethodStacks。 3)ExecutionEngine由Interpreter、JITCompiler和GarbageCollector組成,負責bytecode的執行和優化。

Java'ssafetyandsecurityarebolsteredby:1)strongtyping,whichpreventstype-relatederrors;2)automaticmemorymanagementviagarbagecollection,reducingmemory-relatedvulnerabilities;3)sandboxing,isolatingcodefromthesystem;and4)robustexceptionhandling,ensuringgr

Javaoffersseveralkeyfeaturesthatenhancecodingskills:1)對象 - 方向 - 方向上的allowslowsmodelowsmodelingreal-worldentities

thejvmisacrucialcomponentthatrunsjavacodebytranslatingitolachine特定結構,影響性能,安全性和便攜性。 1)theclassloaderloader,links andinitializesClasses.2)theexecutionEngineExecutionEngineExecutionEngineExecuteNexeCuteByteCuteByteCuteByTecuteByteCuteByteCuteBytecuteBytecuteByteCoDeinintolachineinstructionsions.3)Memo.3)Memo


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

Dreamweaver Mac版
視覺化網頁開發工具

記事本++7.3.1
好用且免費的程式碼編輯器

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境