Передача одного запускаемого объекта нескольким конструкторам потоков
Если я создаю runnable object
Runnable run = new MyRunnable();
И затем передайте один и тот же точный объект двум конструкторам потоков и запустите их
new Thread(run).start;
new Thread(run).start;
- Возможно ли это? Каковы последствия?
- Если я вызываю Thread.sleep(0); в классе MyRunnable будут ли обе нити засыпать, потому что они являются одним и тем же объектом, или сущность потока полностью отделена от объекта?
- Будет ли когда-нибудь причина для этого, если не все равно ответьте на два вопроса выше, потому что я не думаю, что я полностью понимаю механизм потоков?
Ответы
Ответ 1
-
Это определенно возможно и законно. Если ваш Runnable
не имеет состояния (без полей), тогда все будет в порядке. Если ваш Runnable
имеет изменяемое состояние, вам может потребоваться использовать один из многих механизмов взаимного исключения Java, например ReentrantLock
или ключевое слово synchronized
. Поскольку обе потоки будут мутировать поля одного и того же объекта Runnable
.
-
Нет, вы создали и запускали две разные темы. Они просто называют Runnable.run()
.
-
Это не из сферы возможностей. Я бы даже не сказал, что это плохая практика. Конкретные ситуации, в которых вы могли бы сделать это, оставались в качестве упражнения для читателя...
Ответ 2
1) Возможно ли это? Каковы последствия?
Да, это возможно.
Импликация заключается в том, что любое состояние в Runnable (потенциально) разделяется всеми потоками, а доступ к/обновлению этого состояния должен быть правильно синхронизирован.
2) Если я вызываю Thread.sleep(0); в классе MyRunnable будут обе спящие потоки, потому что они являются одним и тем же объектом, или сущность потока полностью отделена от объекта?
Нет, они не будут.
Тема логически отлична от Runnable
. Вызов Thread.sleep()
напрямую не влияет на Runnable
и другие потоки, которые могут его использовать. (Это может повлиять на другие потоки косвенно, например, если один поток спящий, в то время как он удерживает Runnable-примитивный замок, а другие потоки должны получить блокировку для достижения прогресса.)
3) Было бы когда-нибудь причина для этого, если бы не все еще ответили на два вопроса выше, потому что я не думаю, что я полностью понимаю механизм потока?
Вы можете сделать это, если не существует связанного с потоком состояния, связанного с Runnable
, и вы хотели бы минимизировать накладные расходы на время или накладные расходы инициализации Runnable
. Но такие практики редко встречаются на практике.
В подавляющем большинстве случаев использования в реальном мире каждый поток нуждается в отдельном экземпляре Runnable
.