Почему синхронизированный метод позволяет нескольким потокам работать одновременно? - PullRequest
8 голосов
/ 05 октября 2011

У меня есть следующая программа в том же файле. Я синхронизировал метод run ().

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

вывод

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

Мой вопрос: почему синхронизированный метод допускает одновременный доступ к потокам «Моя тема 1» и «Моя тема 4»?

1 Ответ

30 голосов
/ 05 октября 2011

synchronized методы работают на уровне экземпляра. Каждый экземпляр класса получает свою собственную блокировку.Блокировка получается каждый раз, когда вводится любой synchronized метод экземпляра.Это позволяет нескольким потокам вызывать synchronized методы в одном экземпляре (обратите внимание, что это также предотвращает вызов методов различных synchronized в одном экземпляре).

Теперь, так как у вас есть два экземпляра вашего класса, каждый экземпляр получает свою собственную блокировку.Ничто не мешает двум потокам, каждый из которых работает одновременно со своим собственным экземпляром.

Если вы хотите предотвратить это, вы можете иметь блок synchronized(obj) внутри run(), где obj будет некоторым объектомобщий для обоих экземпляров вашего класса:

class MyThread2 implements Runnable {
   private static final Object lock = new Object();
   ...
   public void run() {
     synchronized(lock) {
       ...
     }
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...