Java запуск пула потоков в конструкторе объектов
Безопасно ли запускать пул потоков в конструкторе объектов? Я знаю, что вы не должны запускать поток из конструктора, что-то о побеге указателя "this" (я не совсем понимаю это, но сделаю еще несколько поисков, чтобы попытаться понять это).
Код будет выглядеть примерно так:
private ExecutorService pool;
public handler()
{
pool = Executors.newCachedThreadPool();
}
public void queueInstructionSet(InstructionSet set)
{
pool.submit(new Runnable that handles this instruction set);
}
Если это не сработает, я могу просто создать этот класс как управляемый и запустить его в новом потоке. Однако, похоже, что это было бы добавление ненужного поток к программе, где он действительно не нужен.
Спасибо.
Правка:
Спасибо всем за ответы, они определенно помогли разобраться в этом.
В соответствии с кодом, на мой взгляд, имеет смысл, что этот конструктор создает пул потоков, но позвольте мне объяснить, что конкретно делает этот код, потому что я могу думать об этом странным образом.
Весь смысл этого объекта состоит в том, чтобы взять" наборы инструкций " объектов и действовать на них соответственно. Наборы команд поступают от клиентов, подключенных к серверу. Как только полный набор команд получен от клиента, этот набор команд отправляется этому объекту (обработчику) для обработки.
Этот объект обработчика содержит ссылку на каждый объект, на который может действовать набор команд. Он отправит набор команд в пул потоков, который найдет, с каким объектом этот набор команд хочет взаимодействовать, а затем обработает набор команд для этого объекта.
I я мог бы обрабатывать объект набора инструкций на сервере ввода-вывода, но у меня есть отдельный класс, поскольку он делает весь код более читаемым, так как каждый класс фокусируется на выполнении только одной конкретной вещи.
Мысли? Совет?
Спасибо
4 ответов:
Ваш пример кода вообще не позволяет" этому " убежать. Достаточно безопасно запускать новый поток в конструкторе (и даже использовать
thisв качествеRunnable, чего вы не делаете в этом примере), если вы уверены, что уже инициализировали объект настолько, насколько это потребуется новому потоку. Например, установка конечного поля, на которое будет опираться новый поток после запуска потока, была бы очень плохой идеей :)В основном, позволяя" этой " ссылке бежать, это вообще противно, но не везде так. Есть ситуации, в которых это безопасно. Просто будь осторожен.
Сказав это, создание конструктора для запуска потока может рассматриваться как выполнение слишком многого внутри конструктора. Трудно сказать, уместно ли это в данном случае - мы недостаточно знаем о том, что делает ваш код.
EDIT: да, прочитав дополнительную информацию, я думаю, что это нормально. Вероятно, у вас должен быть метод для завершения работы пула потоков как хорошо.
Я согласен с Джоном.
Кроме того, позвольте мне указать, что вы фактически не запускаете никаких действий в пуле потоков в конструкторе. Вы создаете экземпляр пула потоков, но на этом этапе у него нет задач для запуска. Поэтому, как было написано, вы не будете иметь что-то начать работать на этом экземпляре, прежде чем он закончит строительство.
Похоже, что пул потоков будет принадлежать и использоваться объектом; потоки не будут передаваться из объекта. Если это так, то это не должно быть проблемой.
КонструкторыСоздают объект и инициализируют его состояние. Я не могу представить себе случай использования, когда для этого требуются длительные процессы.
Я вижу, где объект может взаимодействовать с пулом потоков для выполнения задачи, но я не вижу необходимости в том, чтобы этот объект владел пулом потоков.
Подробнее может помочь.
Я думаю, что можно запустить пул потоков в конструкторе объекта, если этот объект полностью управляет временем жизни этого пула потоков.
Если вы пойдете по этому пути, вам придется приложить дополнительные усилия, чтобы обеспечить следующие гарантии:
- Если конструктор создает какое-либо исключение ( как во время выполнения, так и при проверке), в конструкторе должен быть код очистки, который завершает работу пула потоков. Если вы не сделаете этого и не создадите пул потоков с не-демоническими потоками, то, например, небольшая консольная программа, использующая ваш объект, может оставаться в рабочем состоянии вечно, что приведет к утечке ценных системных ресурсов.
- Вам нужно предоставить что-то, что я называю
destructorметод, подобныйcloseв Java I/O. я обычно называю егоreleaseResources. Обратите внимание, чтоfinalizeне является заменой для этого метода, потому что он вызывается GC, и для объекта с относительно небольшим объемом памяти он может никогда не вызываться.- при использовании этого объекта выполните следующее шаблон
->
MyThreadPoolContainer container = new MyThreadPoolContainer( ... args to initialize the object... ); try { methodThatUsesContainer( container ); } finally { container.releaseResources( ); }
- документ, что конструктор объектов выделяет ограниченные ресурсы и метод
destructorдолжен быть вызван явно, чтобы предотвратить их утечку.
Comments