Java 同步綜合指南
已發表: 2022-05-20在我們解釋Java 中的同步之前,我們必須簡要回顧一下多線程的概念。 Java 的多線程特性允許同時執行程序的兩個或多個部分,以最大限度地利用 CPU。 這樣一個程序的每一部分都是一個線程,線程是一個進程中的輕量級進程。
現在,一個程序的多個線程可能會嘗試訪問相同的資源並產生不准確的結果。 因此,必須有一些同步來確保在給定的時間點只有一個線程可以訪問資源。
這篇關於什麼是 Java 同步的指南將通過示例詳細探討同步的概念。
Java中的同步是什麼?
Java 同步是控制多個線程對共享資源的訪問的能力。 當多線程 Java 程序嘗試訪問同一資源並產生錯誤結果時,它很有用。 使用 Java 同步功能,在給定時間點只有單個線程可以訪問資源。
Java 提供了一種使用同步塊同步線程任務的方法,這些同步塊在同一對像上同步,並且一次只能在其中執行一個線程。 這些塊用 synchronized 關鍵字標記,阻止任何其他試圖進入同步塊的線程,直到已經在塊內的線程結束執行並離開塊。
編寫同步塊的語法
在 Java 中編寫同步塊的一般語法如下:
同步(鎖定對象)
{
// 同步語句
}
在上面的語法中, lockObject是指一個對象,其鎖與同步元素相關。 現在,這將我們帶到 Java 中的鎖概念。
Java中的鎖
Java 中的同步是圍繞鎖或監視器構建的。 每個對像都有一個關聯的鎖。 理想情況下,需要訪問對象字段的線程必須首先獲得對象的鎖。 鎖是一種比同步塊更複雜、更靈活的線程同步機制。 它在包含大量鎖實現的 java.util.concurrent.lock 包中定義。
從世界頂級大學學習在線軟件開發課程。 獲得行政 PG 課程、高級證書課程或碩士課程,以加快您的職業生涯。
Java同步方法
Java 同步方法的目的是為共享資源鎖定對象。 因此,當線程調用同步方法時,該方法會自動獲取該對象的鎖,並在線程執行其作業時釋放它。
下面是一個 Java 同步方法的示例:
//java同步方法的例子
類表{
synchronized void printTable(int n){//同步方法
for(int i=1;i<=5;i++){
System.out.println(n*i);
嘗試{
線程.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
MyThread1 類擴展 Thread{
藥片;
MyThread1(表 t){
這.t=t;
}
公共無效運行(){
t.printTable(5);
}
}
MyThread2 類擴展 Thread{
藥片;
MyThread2(表 t){
這.t=t;
}
公共無效運行(){
t.printTable(100);
}
}
公共類TestSynchronization2{
公共靜態無效主要(字符串參數[]){
Table obj = new Table();//只有一個對象
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
輸出:
5
10
15
20
25
100
200
300
400
500
沒有同步會發生什麼?
現在,讓我們看看前面沒有同步的程序(注意沒有 synchronized 關鍵字)。
類表{
void printTable(int n){//方法不同步
for(int i=1;i<=5;i++){
System.out.println(n*i);
嘗試{
線程.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
MyThread1 類擴展 Thread{
藥片;
MyThread1(表 t){
這.t=t;
}
公共無效運行(){
t.printTable(5);
}
}
MyThread2 類擴展 Thread{
藥片;
MyThread2(表 t){
這.t=t;
}
公共無效運行(){
t.printTable(100);
}
}
類 TestSynchronization1{
公共靜態無效主要(字符串參數[]){
Table obj = new Table();//只有一個對象
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
輸出:
5
100
10
200
15
300
20
400
25
500
如您所見,沒有同步,輸出是不一致的。
探索我們流行的軟件工程課程
SL。 不 | 軟件開發計劃 | |
1 | LJMU & IIITB 計算機科學碩士 | 加州理工學院 CTME 網絡安全證書課程 |
2 | 全棧開發訓練營 | 區塊鏈中的 PG 程序 |
3 | 軟件開發行政研究生課程 - DevOps 專業化 | 查看所有軟件工程課程 |
Java中的同步類型
要回答什麼是 Java 中的線程同步,我們有兩種可用的同步類型:線程同步和進程同步。
讓我們了解每個含義。
線程同步:當多個線程試圖訪問一個共享資源時,我們必須確保該資源一次只被一個線程使用。 線程同步是當多個線程試圖同時使用共享資源時,只允許一個線程使用共享資源的過程。
進程同步:指多個進程同時執行,以達到進程提交到適當的執行順序的狀態。 當兩個或多個進程協作時,需要進程同步,並且一個進程的執行會影響另一個進程。 因此,進程同步消除了輸出不准確的可能性並保證了正確的執行順序。
Java中的同步方法
概括地說,Java 中有四種同步方法:
- 同步的靜態方法
- 同步實例方法
- 靜態方法中的同步塊
- 實例方法內的同步塊
讓我們更詳細地了解 Java 同步的每種方法。
同步的靜態方法
在這裡,我們使用 synchronized 關鍵字來標記 Java 中的靜態方法。 下面是一個 Java 同步靜態方法的示例:
公共靜態 MyStaticCounter {
私有靜態int計數= 0;
公共靜態同步無效增量(整數值){
計數 += 值;
}
}
同步實例方法
當使用帶有實例方法的同步塊時,每個對像都有其同步方法。 每個對像只能有一個可以在方法內部執行的線程。 如果有多個對象,則可以為塊內的每個對象執行單個線程。
公共類 MyCounter {
私人int計數= 0;
公共同步無效增量(整數值){
this.count += 值;
}
公共同步無效減量(整數值){
this.count -= 值;
}
}
靜態方法中的同步塊
下面是我們在靜態方法中使用同步塊的示例:
公共類 MyClass {
公共靜態無效打印(字符串消息){
同步(MyClass.class){
log.writeln(消息);
}
}
}
實例方法內的同步塊
我們可以在方法中的特定塊上使用同步,而不是同步整個方法。 下面是一個非同步方法中的同步代碼塊示例:
公共無效增量(整數值){
同步(這個){
this.count += 值;
}
}
Java 中的同步需求
既然您知道什麼是 Java 中的同步,您可能想知道我們為什麼首先使用它。
Java synchronized 關鍵字提供了並發編程所必需的功能。 以下是 Java 中的同步如何提供幫助:
- Java 同步提供了鎖定功能來消除線程之間的任何競爭條件並確保對共享資源的互斥訪問。
- Java 同步鎖定同時提供鎖定和解鎖功能。 因此,線程需要在進入同步方法或塊之前獲取鎖。
- synchronized 關鍵字防止編譯器對程序語句重新排序。
結論
總而言之,Java 中的同步確保一次只有一個線程可以訪問共享資源。 我們可以使用 Java synchronized 關鍵字使塊或方法同步。 當一個線程想要進入一個同步塊時,它必須獲得一個鎖,離開這個塊後,線程釋放鎖。 我們可以在方法中或在方法塊中使用 synchronized 關鍵字。
想知道在哪裡學習 Java?
upGrad 的軟件工程與工作相關的 PG 認證 就是你要找的!
upGrad 的軟件工程與工作相關的 PG 認證專為應屆畢業生和最後幾年設計,非常適合那些想要學習編程並擔任入門級軟件角色的人。 這個為期 5 個月的在線課程將教授 Java、JavaScript、HTML5、DSA、AWS、MERN 等頂級軟件技能!
問:為什麼我們在 Java 中使用同步?
A:Java 中的 synchronized 關鍵字確保一次只有一個線程可以訪問共享資源。 當多線程 Java 程序嘗試訪問相同的資源並產生不准確的結果時,它很有用。
問:Java 中的同步是如何實現的?
答:Java 使用監視器的概念實現同步,在給定時間只有一個線程擁有監視器。 當一個線程獲得一個鎖時,它就可以訪問監視器,並且所有其他試圖進入鎖定監視器的線程保持阻塞狀態,直到第一個線程離開監視器。
問:Java 中的死鎖是什麼?
A:Java 死鎖發生在一個線程正在等待對象鎖,但另一個線程獲取它,而第二個線程正在等待第一個線程獲取的對象鎖。 因此,兩個線程都在等待對方釋放鎖,從而導致死鎖。