Кто-то может кратко объяснить на том, КАК и КОГДА использовать ThreadFactory? Пример с и не используя ThreadFactory мог бы быть действительно полезным для понимания различий.
Спасибо!
Модель фабрики - это модель проектирования, используемая в разработке программного обеспечения для инкапсуляции процессов, связанных с созданием объектов.
Предположим, у нас есть несколько рабочих потоков для различных задач, и мы хотим присвоить им специальные имена (скажем, для целей отладки). Тогда мы могли бы реализовать ThreadFactory:
public class WorkerThreadFactory implements ThreadFactory {
private int counter = 0;
private String prefix = "";
public WorkerThreadFactory(String prefix) {
this.prefix = prefix;
}
public Thread newThread(Runnable r) {
return new Thread(r, prefix + "-" + counter++);
}
}
Если бы у вас было такое требование, было бы довольно сложно реализовать его без фабрики или паттерна builder.
ThreadFactory
является частью Java API, потому что он используется и другими классами. Таким образом, приведенный выше пример показывает, почему в некоторых случаях нам следует использовать "фабрику для создания потоков", но, конечно, нет никакой необходимости реализовывать java.util.concurrent.ThreadFactory
для выполнения этой задачи.
Как упоминалось в «InsertNickHere», вы должны понимать заводской шаблон .
Хорошим примером использования ThreadFactory является ThreadPoolExecutor : При необходимости исполнитель создаст потоки и позаботится о пуле. Если вы хотите вмешаться в процесс создания и дать специальные имена созданным потокам или назначить их ThreadGroup, вы можете создать ThreadFactory для этой цели и передать его исполнителю.
Это немного в стиле IoC .
ИМХО, самая важная функция ThreadFactory
- это наименование потоков чего-то полезного. Наличие потоков в трассировке стека с именем pool-1-thread-2
или хуже Thread-12
является полной болью при диагностике проблем.
Конечно, наличие ThreadGroup
, статус демона и приоритет тоже полезны.
Вот одно из возможных вариантов использования. Если у вас есть служба-исполнитель, которая выполняет ваши выполняемые задачи в многопоточном режиме, и время от времени ваш поток умирает из-за неперехваченного исключения. Предположим, вы не хотите регистрировать все эти исключения. ThreadFactory
решает эту проблему:
ExecutorService executor = Executors.newSingleThreadExecutor(new LoggingThreadFactory());
executor.submit(new Runnable() {
@Override
public void run() {
someObject.someMethodThatThrowsRuntimeException();
}
});
LoggingThreadFactory
может быть реализован следующим образом:
public class LoggingThreadFactory implements ThreadFactory
{
@Override
public Thread newThread(Runnable r)
{
Thread t = new Thread(r);
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
@Override
public void uncaughtException(Thread t, Throwable e)
{
LoggerFactory.getLogger(t.getName()).error(e.getMessage(), e);
}
});
return t;
}
}