Java запускает пул потоков в конструкторе объектов - PullRequest
2 голосов
/ 16 августа 2010

Безопасно ли запускать пул потоков в конструкторе объектов?Я знаю, что вы не должны запускать поток из конструктора, что-то об экранировании указателя «this» (я не совсем понимаю это, но сделаю еще несколько поисков, чтобы попытаться выяснить это).

Код будет выглядеть примерно так:

private ExecutorService pool;

public handler()
{
  pool = Executors.newCachedThreadPool();
}

public void queueInstructionSet(InstructionSet set)
{
  pool.submit(new Runnable that handles this instruction set);
}

Если это не сработает, я могу просто создать этот класс как Runnable и запустить его в новом потоке.Однако, похоже, что это добавление ненужного потока в программу, где он на самом деле не нужен.

Спасибо.

РЕДАКТИРОВАТЬ:

Спасибо за ответывсе, они определенно помогли понять это.

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

Весь смысл этого объекта в том, чтобы взять объекты "Наборы инструкций" и действовать на них соответственно.Наборы инструкций приходят от клиентов, подключенных к серверу.Как только полный набор инструкций получен от клиента, этот набор инструкций отправляется этому объекту (обработчику) для обработки.

Этот объект-обработчик содержит ссылку на каждый объект, на который может действовать набор инструкций.Он отправит набор инструкций в пул потоков, который найдет, с каким объектом этот набор инструкций хочет взаимодействовать, и затем обработает набор инструкций для этого объекта.

Я мог бы обработать объект набора инструкций в IOсервер, но мои мысли имеют отдельный класс, поскольку он делает весь код более читабельным, поскольку каждый класс сосредоточен на выполнении только одной конкретной задачи.

Мысли?Совет?

Спасибо

Ответы [ 4 ]

2 голосов
/ 16 августа 2010

Ваш пример кода вообще не позволяет "этому" сбежать. Достаточно безопасно начать новый поток в конструкторе (и даже использовать this в качестве Runnable, чего нет в этом примере), если вы уверены, что уже инициализировали объект как новый поток будет нуждаться в этом. Например, установка окончательного поля, на которое новый поток будет опираться после запуска потока, будет очень плохой идеей:)

По сути, разрешение "this" для ссылки - это обычно противно, но не всегда так. Есть ситуации, в которых это безопасно. Просто будь осторожен.

Сказав это, заставить конструктор запустить поток может показаться слишком большим внутри конструктора. Трудно сказать, уместно ли это в этом случае или нет - мы недостаточно знаем о том, что делает ваш код.

РЕДАКТИРОВАТЬ: Да, прочитав дополнительную информацию, я думаю, что это нормально. Вероятно, у вас должен быть способ завершить пул потоков.

1 голос
/ 16 августа 2010

Похоже, что пул потоков будет принадлежать и использоваться объектом; потоки не будут выходить из объекта. Если это так, это не должно быть проблемой.

Конструкторы создают объект и инициализируют его состояние. Я не могу представить вариант использования, когда для этого требуются длительные процессы.

Я вижу, где объект может взаимодействовать с пулом потоков для выполнения задачи, но я не вижу необходимости для этого объекта владеть пулом потоков.

Более подробная информация может помочь.

1 голос
/ 16 августа 2010

Я согласен с Джоном.

Кроме того, позвольте мне указать, что вы фактически не запускаете никаких действий с пулом потоков в конструкторе. Вы создаете пул потоков, но у него нет задач для запуска в этот момент. Поэтому, как написано, у вас не получится запустить что-то на этом экземпляре до того, как он завершит построение.

0 голосов
/ 16 августа 2010

Я думаю, что можно запускать пул потоков в конструкторе объекта, если этот объект полностью управляет временем жизни этого пула потоков.

Если вы пойдете по этому пути, вам придется приложить дополнительные усилия, чтобы предоставить следующие гарантии:

  1. Если ваш конструктор выдает какое-либо исключение (как во время выполнения, так и проверенное), у вас должен быть код очистки в конструкторе, который закрывает пул потоков. Если вы не сделаете этого и не создадите пул потоков с потоками, не являющимися демонами, то, например, небольшая консольная программа, которая использует ваш объект, может работать вечно, теряя ценные системные ресурсы.
  2. Вам нужно предоставить метод, который я вызываю destructor, аналогично close в Java I / O. Я обычно называю это releaseResources. Обратите внимание, что finalize не является заменой этого метода, потому что он вызывается GC, а для объекта с достаточно малым объемом памяти его нельзя вызывать.
  3. При использовании этого объекта следуйте этой схеме

->

MyThreadPoolContainer container =
    new MyThreadPoolContainer( ... args to initialize the object... );

try
{
  methodThatUsesContainer( container );
}
finally
{
  container.releaseResources( );
}
  1. Документировать, что конструктор объекта выделяет ограниченные ресурсы, и метод destructor должен быть вызван явно, чтобы предотвратить их утечку.
...