2012-05-13 51 views
12

考慮下面的代碼:在一個實例中的Java兩個同步的方法

public class SynchronizedCounter extends Thread { 
    private int c = 0; 

    public synchronized void increment() { 
     c++; 
    } 

    public synchronized void decrement() { 
     c--; 
    } 

    public void run() { 
     for(;;) 
      increment(); 
    } 
} 

static void main(String[] args) { 
    SynchronizedCounter counter = new SynchronizedCounter(); 
    counter.start(); 
    for(;;) 
     counter.decrement(); 
} 

這是否意味着增量()遞減()方法將等待對方完成與否?

編輯: 這不等待?

static void main(String[] args) { 
    SynchronizedCounter counter1 = new SynchronizedCounter(); 
    SynchronizedCounter counter2 = new SynchronizedCounter(); 
    counter1.start(); 
    for(;;) 
     counter2.decrement(); 
} 

回答

13

是的,​​關鍵字是一個速記:

synchronized(this) { 
    //... 
} 

所以,這兩種方法都有效地鎖定相同的互斥對象。如果你希望它們彼此獨立(在這個例子中這是一個壞主意,因爲它們都訪問相同的值),請參閱Object locking private class members - best practice? (Java)

順便說一下,你的SynchronizedCounter應該實現Runnable,而不是擴展Thread因爲你傳遞給其他線程的構造函數 - 現在有點混亂。

+0

是啊,你說得對有關擴展線程,只是修復了代碼:) – MBZ

6

鎖總是整個對象上。如果其中有​​成員被訪問。

在你的第一個例子中,有兩個線程競爭同一個counter對象,一個你開始明確(它調用increment()方法無限循環),另一個線程是主線程(它調用decrement()無限地)。

在第二個例子中,有兩個對象創建counter1counter2。這些將有彼此獨立的自己的鎖。鎖定一個對象不會影響其他線程訪問其他對象。兩個線程(顯式和主線程)獲取兩個不同對象的鎖,因此在中沒有爭用

1

這是否意味着增量()和遞減()方法將等待對方完成或沒有?

,這意味着當一個線程在其中時,沒有其他線程能夠調用increment()和decrement()。是完整的,其他線程無法執行此實例/對象的任何synchronized方法

你可以稱之爲從一個同步的任何其它synchronized方法無鎖相同的實例/對象

相關問題