2010-07-29 40 views
11

當我們談論固有鎖時,我們引用我們要求鎖 或對於同步方法的對象?線程固有鎖

鎖是在對象上還是在它的同步方法?

我很困惑!

回答

4

同步方法鎖定在物體上的方法

synchronized void methodA() { 
    ....  
} 

在某種程度上相當於

void methodA() { 
    synchronized (this) { 
     .... 
    } 
} 
+0

每個對象都有一個內部鎖。這兩個語句是等價的,因爲兩者都在包含methodA()的對象的內部鎖定上進行同步。 – Brandon 2013-02-01 22:06:10

+0

向不懂理解同步方法的人解釋同步語句不是一個好主意。這使我更加困惑。 – 2014-07-12 02:11:45

15

內在鎖是在對象上:

class A 
{ 
    public synchronized void method1(){...} 
    public synchronized void method2(){...} 
} 

如果線程A是在方法1那麼threadB不能輸入method2。

+1

我希望,Stackoverflow允許我爲你的最後一行加上+10。 :) – UnKnown 2015-10-03 22:08:32

1

鎖是對象的一部分。每個對象具有一個和它可以被鎖定在兩種方式:

  1. 使用關於類的實例方法的​​改性劑來鎖定相關聯的對象
  2. 使用synchronized(object) {}

類似地,你可以鎖定一個對象的類而不是對象本身(爲了解​​修改器,用static方法分開提及):

  1. 使用的類的一個靜態方法的​​改性劑以鎖定類
  2. 使用synchronized(clazz) {}塊,其中clazz是Object
0

的類鎖是在對象上。在Java中的每一個對象是一個monitor

9

在Java中,一個內部鎖是由每個使用

synchronized關鍵字中的每一個使用與兩種類型的內部鎖中的一個相關聯的同步關鍵字的暗示:

「實例鎖」,連接到單個對象

「靜態鎖」,附加到類

如果一個方法被聲明爲同步的,那麼它會獲得任一實例鎖或者調用時的靜態鎖,根據它是實例方法還是靜態方法。

這兩種類型的鎖具有相似的行爲,但彼此完全獨立。

獲取實例鎖只會阻止其他線程調用同步實例方法;它不會阻止其他線程調用未同步的方法,也不會阻止它們調用靜態同步方法。

同樣,獲取靜態鎖只會阻止其他線程調用靜態同步方法;它不會阻止其他線程調用未同步的方法,也不會阻止它們調用同步的實例方法。

在方法頭之外,synchronized(this)獲取實例鎖。

靜態鎖可以的方法報頭之外以兩種方式獲得:

同步(Blah.class),使用類字面

同步(this.getClass()),如果對象可用

0
private int count = 0; 
public synchronized void countFunc(){ 
     count++; 
    } 
Thread t1 = new Thread(new Runnable(){ 
      public void run(){ 
      for(int i=0;i<1000;i++){ 
       countFunc(); 
       }}}); 
     Thread t2 = new Thread(new Runnable(){ 
      public void run(){ 
      for(int i=0;i<1000;i++){ 
       countFunc(); 
      }}}); 

在上面的例子中,我有2個線程試圖增加count的值。並且爲了防止線程交錯,我試圖通過使用同步關鍵字來獲取固有鎖。

決定性, 在這個例子中,方法塊countFunc同步關鍵字和計數變量。 希望這可以幫助

0

鎖在對象上。

看一看Java教程頁面上intrinsic locks

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

只要線程擁有內部鎖,其他線程就不會獲得相同的鎖。另一個線程在嘗試獲取鎖時會阻塞。

兩種方式使用內部鎖:

  1. 同步方法:

    當一個線程調用​​方法,它會自動獲取內部鎖該方法的對象,當方法返回時釋放它。

    例如

    public synchronized void incrementCounter(){ 
        ++counter; 
    } 
    
  2. 同步語句

    不同於​​方法,​​語句必須指定提供了內部鎖

    public int getCounter(){ 
        synchronized(this){ 
         return counter; 
        } 
    } 
    

    完整的示例對象:

    public class SynchronizedDemo{ 
    private int counter = 0; 
    
    public SynchronizedDemo(){ 
    
    } 
    public synchronized void incrementCounter(){ 
        ++counter; 
    } 
    public int getCounter(){ 
        synchronized(this){ 
         return counter; 
        } 
    } 
    public static void main(String[] args){ 
        SynchronizedDemo object = new SynchronizedDemo(); 
        for (int i=0; i < 5; i++){ 
         Thread t = new Thread(new SimpleRunnable(object)); 
         t.start(); 
        }   
    } 
    } 
    class SimpleRunnable implements Runnable{ 
    private SynchronizedDemo object; 
    
    public SimpleRunnable(SynchronizedDemo obj){ 
        this.object = obj; 
    } 
    public void run(){ 
        object.incrementCounter(); 
        System.out.println("Counter:"+object.getCounter()); 
    } 
    } 
    

注意:本示例僅用於展示使用內部鎖的不同方式。對於這種類型的用例,使用AtomicInteger作爲計數器變量是正確的方法。