порядок вызова синхронизированных методов

java multithreading

86 просмотра

2 ответа

Я полагаю, это простой вопрос, но все же, я не понимаю его самостоятельно. Скажи, у меня есть следующий код.

Runnable objectRunnable = new Runnable() {
    void run() {
          synchronized(object) {
              for (int i = 0; i < 5; i++) {
                  System.out.println("it's runnable");
                  Thread.sleep(100); 
              }
          }
    }
};

void doSomething() {
    synchronized(object) {
        for (int i = 0; i < 5; i++) {
            System.out.println("it's doSomething");
            Thread.sleep(100);
        }
    }
}

synchronized (object) {
    new Thread(objectRunnable).start();
}
object.doSomething();

Итак, вывод

it's doSomething
it's doSomething
it's doSomething
it's doSomething
it's doSomething
it's runnable
it's runnable
it's runnable
it's runnable
it's runnable

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

Имеют ли методы самого синхронизированного объекта какой-либо приоритет в выполнении перед любыми потоками, синхронизированными на этом объекте?

Автор: idementia Источник Размещён: 08.11.2019 11:08

Ответы (2)


1 плюс

Решение

То, что у вас есть, это состояние гонки: ваш запускаемый объект блокируется в ожидании на мониторе при запуске из-за synchronized (object)его создания. Как только поток, создающий runnable, освобождает монитор, вновь созданный поток с runnable не получает возможности захватить его, потому что тот же поток повторно вводит его снова в doSomething()метод.

Если вы добавите вызов Thread.sleep(100);перед звонкомobject.doSomething()

synchronized (object) {
    new Thread(objectRunnable).start();
}
Thread.sleep(100); // <<== Add this line
object.doSomething();

порядок распечаток будет обратным ( демо ).

it's runnable
it's runnable
it's runnable
it's runnable
it's runnable
it's doSomething
it's doSomething
it's doSomething
it's doSomething
it's doSomething
Автор: dasblinkenlight Размещён: 20.08.2016 10:04

2 плюса

Потому что основной поток первым получает блокировку. Это мог быть порожденный поток, вы просто не можете быть уверены, хотя это гораздо менее вероятно, потому что после вызова start () требуется некоторое время, чтобы поток фактически начал работать.

Что касается остальной части вашего вопроса, это слишком расплывчато, чтобы ответить.

Автор: JB Nizet Размещён: 20.08.2016 09:57
Вопросы из категории :
32x32