2012-05-13 25 views
12

şu kodu göz önünde bulundurun:Java iki senkronize yöntemler

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(); 
} 

bu artım() ve eksiltme() yöntemleri birbirlerini bitirmek için ya da değil beklemek anlamına gelir mi?

EDIT: ve bu beklemez?

synchronized(this) { 
    //... 
} 

Yani iki yöntem de etkili aynı muteks nesne üzerinde kilitleme gibidir:

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

cevap

13

Evet, synchronized anahtar kelime için bir kısaltmadır. Eğer birbirlerinden bağımsız olmalarını istiyorsanız (bu örnekte her ikisi de aynı değere eriştikleri için kötü bir fikirdir), bkz. Object locking private class members - best practice? (Java).

BTW senin SynchronizedCounter ziyade diğer parçacığının yapıcı geçirmeden çünkü bir Thread uzanan daha Runnable uygulamalıdır - şimdi biraz kafa karıştırıcı.

+0

evet kilidi olmadan senkronize bir birinden başka senkronize bir yöntem diyebiliriz, siz uzanan yaklaşık haklısın bu örnek/nesnenin herhangi senkronize çalıştırma yöntemi olamazdı Konu, sadece kodu sabit :) – MBZ

6

kilidi her zaman tüm nesnenin üzerinde bulunur. Bunlardan herhangi biri synchronized üyesine erişilir. İlk örnekte

, aynıcounter nesne için çekişen iki konu vardır, biri açıkça başladı (sonsuz döngüye increment() yöntemini çağırır olan) ve diğer iplik decrement() çağıran ana iş parçacığı (olduğu sonsuz).

İkinci örnekte, counter1 ve counter2 olmak üzere iki nesne oluşturulmuştur. Bunların birbirinden bağımsız kendi kilitleri olacaktır. Bir nesnenin kilitlenmesi, diğer iş parçacıklarının diğer nesnelere erişmesini etkilemez. İki iş parçacığı (açık ve ana iş parçacığı), iki farklı nesneye ve dolayısıyla hiçbir çekişme'da kilitleme elde eder.

1

bu, arttırma() ve decrement() yöntemlerinin birbirinin bitmesini bekleyip beklemeyeceği anlamına mı geliyor?

NO, başka hiç bir iplik bir iplik içlerindeki olduğunda artışı() ve azaltma() dönmesini mümkün olacağı anlamına gelir. tam olması için, diğer iplik

Aynı örneği/nesne