JavaRush/Java блог/Архив info.javarush/Вопросы про synchronized
plyuspavel
20 уровень

Вопросы про synchronized

Статья из группы Архив info.javarush
участников
Возникло несколько вопросов по теме synchronized.
Вопрос 1 Предположим, у нас есть объект класса, в коде которого изменяется строка как предложено ниже. public class Exxample1 extends Thread{ public String stroka; public void run() { <...> stroka=stroka+" "; //(1) <...> synchronized(stroka) { stroka=stroka+" "; } } } Объект этого класса одновременно используют сразу несколько нитей. Первая нить добралась до блока synchronized и заблокировала строку. Это значит, что все другие нити
  • не смогут зайти внутрь этого блока, пока первая нить не закончит свою работу в нем (заснут)
  • не смогут использовать строку stroka, где бы ее не вызвали(заснут). То есть команда (1) не будет выполнена пока первая нить не выйдет из блока.
  • оба пункта
  • другое
Вопрос 2 У нас есть объект класса, который используется одновременно несколькими нитями (код класса ниже) public class Example2 extends Thread { public void run() { <...> synchronized(this) { <...> } } } Какие утверждения, приведенные ниже верны. Когда одна из нитей заходит в блок synchronized...
  • все остальные нити, которые уже работают с этим объектом заснут
  • нити, уже использующие этот объект продолжат свою работу, но новые будут ждать разблокировки объекта (заснут)
  • все нити, использующие этот объект или только собирающиеся его использовать заснут (объединение первых двух пунктов)
  • другое
Вопрос 3 Ниже приведен код класса, объект которого используется несколькими нитями одновременно. public class Example3 extends Thread { public String s; public int k; private String word; public void run() { <...> synchronized (s) { <...> } <...> synchronized (this) { <...> } } } Одна из нитей заходит в первый блок synchronized и блокирует строку. В этот момент другая нить заходит во второй блок и пытается заблокировать весь объект, но строка s уже заблокирована. Что же произойдет?
  • вторая нить все равно заблокирует весь объект, первая - заснет
  • вторая нить все равно заблокирует весь объект, первая продолжит свою работу (а что тогда с s? будет использоваться обеими нитями или заблокирована для всех?)
  • вторая нить заснет, будет ждать выхода первой нити из блока
  • другое
Вопрос 4 Если использовать synchranized в описании метода, то когда нить вызовет этот метод, все треды, использующие объект, в котором описан данный метод, заснут? (Вроде ответ должен быть аналогичен ответу 2ого вопроса) Спасибо за ваши ответы. Тема, действительно, сложная и несколько мутная. Надеюсь на ваше понимание. Кстати, можете подкинуть доп. ссылок или литературы на эту тему (коме уже указанных в JavaRush).
Комментарии (4)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
tanzwud
Уровень 34
4 сентября 2014, 20:42
Лови
Вопрос 1.
1 они не заснут а попадут в blocked set
2 т.к. public String stroka; следовательно другие нити
могут изменять строку.
3 не подходит
4 другое это правильный ответ.

Вопрос 2.
Заснут как по мне неверное трактование работы синхронайзед.
Thread.sleep(milis) поток засыпает.
Syncronized — поток может попасть в Blocked состояние
где он не run но alive, blocked состояние — будет ждать нужный ресурс.

4. Ответ другое. Т.к. как минимум слово заснут неправильно.
Как работает монитор по обьекту.
Если один поток захватил обьект. Все все остальные потоки будут
blocked. Тоесть ждать пока поток выйдет из syncronized блока и отпустит
монитор

Вопрос 3.
4. Другое.
Правильный ответ в данном случае может быть как минимум
2 варинта.
NullPointerException выбросится т.к. public String s не инициализирован.
Плюс. Т.к. publuc String s имеет модификатор public и поле не финальное к
нему могут получить доступ другие потоки изменить его или еще что
в итоге что получится тяжело узнать.

Если переменна s инициализирована — тогда МОЖЕТ получится либо deadlock
либо Nothing can be said for sure.

Вопрос 4.
Нет не заснут. Переместятся в blocked set где будут ждать освобождения
монитора. Если не брать в расчет wait/notify методы когда под
syncronized блоком может быть несколько потоков.
A synchronized method cannot be executed simultaneously by more than one thread on the same object.

In which of the following cases a thread will definitely be alive but not be running?
The thread is trying to enter a synchronized block and the monitor is not free.
The thread is sleeping as a result of a call to the sleep( ) method.

Лучшие книги по Java Core Это любые книги по подготовке к тестированию.
Sun Certified Programmer for Java 6 Katt
plyuspavel
Уровень 20
4 сентября 2014, 20:54
Спасибо огромное за развернутый ответ! Небольшое уточнение по поводу первого вопроса: ты написал, что
т.к. public String stroka; следовательно другие нити
могут изменять строку.
те получается, что синхронизировать отдельные объекты(не методы и не блоки кода) бессмысленно, или я чего-то не так понял?
PS Я везде использовал «заснут», тк данное понятие использовалось в лекциях. Хотя ты, конечно, прав, не заснут, а заблокируются
tanzwud
Уровень 34
4 сентября 2014, 21:36
модификатор public значит что это поле можно изменять не только через методы но и напрямую. Чтобы синхронизация работала правильно нужно применять инкапсуляцию.
Синхронизация помогает потокам получить правильно доступ к общим ресурсам.
plyuspavel
Уровень 20
4 сентября 2014, 17:33
Никто не хочет ответить на 4 интересных вопроса...(