2011-10-05 10 views
7

Mam następujący program w tym samym pliku. Zsynchronizowałem metodę run().Dlaczego metoda zsynchronizowana umożliwia jednoczesne uruchamianie wielu wątków?

class MyThread2 implements Runnable { 
    Thread t; 

    MyThread2(String s) { 
     t=new Thread(this,s); 
     t.start(); 
    } 

    public synchronized void run() { 
     for (int i=0;i<3;i++) { 
      System.out.println("Thread name : "+ Thread.currentThread).getName()); 
      try { 
       t.sleep(1000); 
      } 
      catch (InterruptedException e) { 
       e.getMessage(); 
      } 
     } 
    } 
} 

class TestSync { 
    public static void main(String[] args) { 
     MyThread2 m1=new MyThread2("My Thread 1"); 
     c.fun(); 
    } 
} 

class c { 
    static void fun() { 
     MyThread2 m1=new MyThread2("My Thread 4"); 
    } 
} 

wyjście jest

Thread name : My Thread 1 
Thread name : My Thread 4 
Thread name : My Thread 4 
Thread name : My Thread 1 
Thread name : My Thread 1 
Thread name : My Thread 4 

Moje pytanie jest dlaczego jest zsynchronizowany sposób umożliwiający zarówno "Mój wątek 1" i "My wątku 4" dostęp wątku współbieżnie?

+2

Kod pan pisał ma co najmniej jedną składnię błąd i jest naprawdę trudny do odczytania. Upewnij się, że publikujesz aktualny kod i spróbuj sformatować go w czytelny sposób. – Mat

+0

Błędne jest to, że blokujesz metodę, zamiast tego masz metodę, która blokuje instancję. –

Odpowiedz

27

synchronized metody działają na poziomie instancji. Każda instancja klasy otrzymuje własną blokadę. Blokada jest pobierana za każdym razem, gdy wprowadzana jest metoda instancji synchronized. Zapobiega to wielu wątkom wywołującym synchronized metod metody w tej samej instancji (należy zauważyć, że to również zapobiega otrzymywaniu metod dla tej samej instancji).

Teraz, ponieważ masz dwa wystąpienia swojej klasy, każda instancja otrzymuje własną blokadę. Nic nie stoi na przeszkodzie, aby dwa wątki działały równocześnie z własną instancją.

Jeśli chcemy tego uniknąć, można mieć synchronized(obj) blok wewnątrz run(), gdzie obj byłby jakiś obiekt udostępniony przez obie instancje klasy:

class MyThread2 implements Runnable { 
    private static final Object lock = new Object(); 
    ... 
    public void run() { 
    synchronized(lock) { 
     ... 
    } 
    } 
} 
+0

Dzięki za odpowiedź – user980089

+0

Jeśli mamy tylko jedno wystąpienie klasy i wiele wątków, czy istnieje możliwość równoczesnego uruchomienia niektórych metod "synchronizowanych"? – Sajad

+0

@ssss: Oczywiście: 'static' vs non -static', używanie bloków' zsynchronizowanych' z różnymi blokadami itp. Jeśli potrzebujesz więcej informacji, opublikuj nowe pytanie. – NPE

Powiązane problemy