Несколько вопросов о Threading в Java
Сначала немного предыстории. В NetBeans я получил предупреждение о том, что не следует создавать новый поток в конструкторе. Я читал, что причина этого в том, что новый поток может запуститься и попытаться сослаться на объект, запустивший поток до того, как конструктор фактически завершит создание объекта.
1.) Для экспериментов вместо использования new Thread
а также thread.start()
Я старался ExecutorService
и я не получил предупреждения. Означает ли это, что это нормально для создания и запуска нового потока в конструкторе, если я использую ExecutorService
?
2.) Кроме того, если у меня есть ExecutorService
в форме кэшированного пула потоков будет создание нового потока стандартным методом new Thread
а также thread.start()
вытащить поток из пула кеша (или заставить его создать, если он не доступен) или эти потоки полностью независимы от пула кэшированных потоков?
3 ответа
1) [...] Означает ли это, что можно создавать и запускать новый поток в конструкторе, если я использую
ExecutorService
?
Общее правило: не пропускайте ссылку на строящийся объект (this
), пока он не будет полностью построен. То есть не отдавай this
к другому therad в конструкторе, не добавляйте себя в качестве слушателя из конструктора и т. д. и т. д.... То есть никогда не используйте this
в качестве параметра функции из конструктора.
2) [...] будет создание новой темы стандартным методом
new Thread
а такжеthread.start()
вытащить поток из пула кеша [...]
Нет, нет пути new
мог быть перегружен, чтобы не создавать свежий объект. В таких случаях вам нужно будет пройти заводской метод.
1) Нет, возможно, это всего лишь ограничение статического анализа NetBeans. Конечно, это можно сделать в любом случае, если вы не пропустите ссылку на объект, который в данный момент создается.
Утечка ссылки на конструируемый объект не только опасна в многопоточных ситуациях. Даже если вы вызываете внешний метод из конструктора, передавая себя в качестве параметра, метод может использовать вас не по назначению.
2) нет, new
всегда создает новый объект, без исключений. Вы идете вокруг пула потоков.
Обязанность конструктора - просто создать объект, если у вас есть объект, расширяющий Thread, вы не должны вызывать start() из конструктора, другой объект должен вызывать start().