Синхронизация методов работает по-разному с различными объектами инициализации - PullRequest
0 голосов
/ 06 декабря 2018

Согласно моему коду, у меня есть три класса:

Отображение:

class Display
{
    synchronized public void wish(String name)
    {
        for(int i = 0; i < 3; i++)
        {
            System.out.print("Good Morning: ");
            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException ie)
            {
            }
            System.out.println(name);
        }
    }
}

MyThread:

class MyThread extends Thread
{
    String name;
    Display d;


    MyThread(Display d, String name)
    {
        this.name = name;
        this.d = d;
    }

    @Override
    public void run()
    {
        d.wish(name); 
    }
}

Демонстрация:

class SynchronizedDemo 
{
    public static void main(String[] args) 
    {
        Display d = new Display();
        MyThread mt1 = new MyThread(d, "foo");
        MyThread mt2 = new MyThread(d, "bar");

        mt1.start();
        mt2.start();
    }
}

Работает нормально, когда я запускаю класс Demo и получаю следующий вывод:

Good Morning: bar
Good Morning: bar
Good Morning: bar
Good Morning: foo
Good Morning: foo
Good Morning: foo

Output completed (6 sec consumed) - Normal Termination

Здесь я полностью понимаю тот факт, что метод sleep () не снимает блокировку объекта, поэтому, как только поток попадает вметод wish () завершает свою работу, тогда шанс может получить только другой поток.

Но если я изменю свой класс MyThread следующим образом:

class MyThread extends Thread
{
    String name;
    Display d;


    MyThread(Display d, String name)
    {
        this.name = name;
        this.d = d;
    }

    Display d1 = new Display();

    @Override
    public void run()
    {
        d1.wish(name); 
    }
}

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

Good Morning: Good Morning: foo
Good Morning: bar
Good Morning: bar
Good Morning: foo
Good Morning: bar
foo

Output completed (3 sec consumed) - Normal Termination

Здесь ясно видно, что, как только один поток переходит в спящий режим, другой получает возможность выполнить wish ().

1 Ответ

0 голосов
/ 06 декабря 2018

Во втором примере d1 является членом класса MyThread, который инициализируется встроенным (который является просто синтаксическим сахаром по сравнению с инициализацией его в конструкторе).Каждый экземпляр MyThread имеет свой собственный экземпляр Display, поэтому синхронизация не имеет смысла - это два разных объекта, синхронизирующихся на двух разных мониторах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...