2011-11-17 96 views
20

我學習java多線程,我發現很難了解如何同步塊的工作:示例代碼顯示Java的synchronized塊是如何工作的

synchronized(Object o){ 
    // do something 
    } 

請給一些示例代碼,可以顯示我的對象o被阻止。至於我如何理解這一點,當正在執行同步塊時,將阻止從另一個線程訪問對象o?

+0

你試過谷歌嗎? –

回答

10

Java中的同步是一個重要的概念,因爲Java是一種多線程語言,其中多個線程並行運行以完成程序執行。在多線程環境中,java對象的同步或java類的同步變得非常重要。 Java中的同步通過使用java關鍵字「synchronized」和「volatile」是可能的。在Java中共享對象的併發訪問引入了一些錯誤:線程干擾和內存一致性錯誤,爲了避免這些錯誤,你需要正確地同步你的java對象。允許臨界區的互斥訪問兩個線程

瞭解更多:http://javarevisited.blogspot.com/2011/04/synchronization-in-java-synchronized.html#ixzz2LOWwnCjH

請看看這個Example

10

synchronized關鍵字可以應用於靜態/非靜態方法或塊代碼 只有一個線程一次可以訪問同步方法,並且如果有多個線程試圖訪問同一個方法,那麼其他線程必須等待一個線程執行方法。 同步關鍵字提供所述對象上的鎖,從而防止競爭條件

簡單的例子:

public void synchronized method(){} 
public void synchronized staticmethod(){} 
public void myMethod(){ 

      synchronized (this){    // synchronized keyword on block of code 
      } 

} 

更多的解釋關於同步塊和方法:
同步塊可以選擇它同步於哪個對象。 一個同步方法只能使用'this'(或用於同步類方法的對應Class實例)。 例如,這些在語義上等價的:

synchronized void foo() { 
    ... 
} 

void foo() { 
    synchronized (this) { 
     ... 
    } 
} 

後者是更靈活的,因爲它可以爲任何對象的相關聯的鎖,通常是一個成員變量競爭。它也更精細,因爲您可以在塊之前和之後執行併發代碼,但仍然在方法中。當然,通過將併發代碼重構爲單獨的非同步方法,您可以輕鬆使用同步方法。使用任何一種方式使代碼更易於理解。

0

同步描述如果一個對象或一個塊被聲明爲同步的,那麼只有一個進程可以一次訪問該對象或塊。沒有其他進程可以接受該對象或塊,直到它可用爲止。在內部,每個對象都有一個標記爲「lock」的標誌有兩個狀態設置和重置。當進程請求一個對象時,檢查鎖定值是否被設置或重置。取決於一個對象可用於進程的同步。爲了更好的理解你的例子,你可以看到這個鏈接。 enter link description here

+0

雖然這可能回答這個問題,但問題已經得到解答。請詳細說明您的答案與已經在這裏(並已被接受)的答案是否有所不同 - 或者它是如何擴展它們的。 –

0

由於大多數答案都涵蓋了什麼同步意味着我想添加一個沒有提到的額外點。 同步方法或使用synchronized同步塊可確保操作/操作集作爲單個原子操作執行,準確地說,當一個線程正在對象上執行同步塊時,其他線程無法進入該塊直到線程完成它的執行並釋放它在進入塊時獲得的鎖。

所以同步塊確保一堆代碼語句的原子性。

與@lucifier指定的不同,Synchronizing和volatile沒有達到同樣的目的,volatile用於確保兩個線程彼此通信,並從主存儲器獲取最新的值,而不是從個人獲取值cache.it還可以確保「執行之前」的行爲。例如,將一個變量定義爲volatile(volatile int i = 10;)在非同步方法中執行增量操作(i ++;)時,(i ++)被封閉在同步塊中時不會給出相同的行爲。

1

內在鎖和同步

同步是圍繞被稱爲內部鎖內部實體內置或監視鎖。 (API規範通常將此實體簡稱爲「監視器」。)在同步的兩個方面(強制對象狀態的獨佔訪問和建立發生)之前,內部鎖都起作用,而這些關係對於可見性至關重要。

每個對象都有與之相關的固有鎖定。按照慣例,需要獨佔且一致地訪問對象字段的線程在訪問對象之前必須先獲取對象的內部鎖,然後在完成內部鎖時釋放內部鎖。據說一個線程擁有它獲取鎖定和釋放鎖定之間的固有鎖定。只要線程擁有內部鎖,其他線程就不會獲得相同的鎖。另一個線程在嘗試獲取鎖時會阻塞。

當一個線程釋放一個內部鎖時,在該動作和任何後續的同一個鎖的獲取之間建立一個發生之前的關係。

鎖在同步方法

當一個線程調用一個同步方法,它自動獲取用於該方法的對象並釋放它的方法返回時的固有鎖。即使返回是由未捕獲的異常引起的,也會發生鎖定釋放。

您可能想知道在調用靜態同步方法時會發生什麼,因爲靜態方法與類關聯,而不是對象。在這種情況下,線程獲取與該類關聯的Class對象的內部鎖。因此,對類的靜態字段的訪問由與該類的任何實例的鎖截然不同的鎖來控制。

相關問題