поведение метода sleep() в блоке синхронизации

class ThreadRunnable implements Runnable{
  synchronized public void run(){       
    System.out.println("In Runnable implemented class");

    try {
        Thread.sleep(60000);
        System.out.println("sleeping over");
        System.out.println(System.currentTimeMillis());
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
  }
}

public class Sample {
    public static void main(String [] args){
        ThreadRunnable tr = new ThreadRunnable();

        Thread t1 = new Thread(tr);

        Thread t2 = new Thread(new ThreadRunnable());

        t1.start();
        t2.start();
    }
}

Поскольку это метод синхронизации, поток t2 должен печатать SOP после t1, но оба потока печатают SOP одновременно. Кто-нибудь может сказать мне, почему?


person nitz    schedule 18.10.2017    source источник
comment
'одновременно'? В любом случае нет никакой гарантии порядка выполнения потоков.   -  person M. le Rutte    schedule 18.10.2017
comment
Подсказка: вы хотите, чтобы мы потратили свое время на решение вашей проблемы. Поэтому, пожалуйста, используйте это окно предварительного просмотра, чтобы проверить отступ вашего ввода до публикации вашего вопроса. И просто для протокола, поскольку об этом так часто забывают: не забывайте в какой-то момент принять один из ответов.   -  person GhostCat    schedule 18.10.2017


Ответы (3)


Метод synchronized неявно синхронизируется с this. В вашем случае экземпляр ThreadRunnable.

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

У вас есть несколько вариантов решения вашей проблемы, например:

  • используйте private static final Object lock = new Object(); в качестве монитора с синхронизированным блоком.
  • или проще Thread t2 = new Thread(tr);
person assylias    schedule 18.10.2017

Вы создаете два экземпляра своего класса.

synchronized предотвращает параллельный вызов метода одного и того же из разных методов.

Это не препятствует параллельному вызову методов для разных объектов!

person GhostCat    schedule 18.10.2017

Взаимного исключения нет. Оба объекта имеют свои собственные отдельные мониторы, которые они приобретают в synchronized, поэтому они оба работают одновременно.

Если вы хотите увидеть разницу, передайте tr и вашему второму потоку. Тогда у вас есть 2 потока, разделяющих 1 объект (и одну блокировку).

person Kayaman    schedule 18.10.2017