Executor framework

Создание потока дорогая операция, для более удобного управления потоками используется Executor framework, а также для кеширования потоков.

Executors.newFixedThreadPool();

Добавляет в пул таски, по мере добавления клиентов до максимального размера пула. Переиспользует ранее созданные потоки. Если поток выдал Runtime исключение, он будет заменен другим потоком. Если делается сабмит новый таски, а пул полностью занят, то таска будет ждать.

Executors.newCachedThreadPool();

Добавляет в пул таски, используя ранее созданные потоки. Если отработанный поток висит какое-то время в состоянии idle, то по истечению 60 сек (это настраивается) он умирает. Этот пул хорош для создания большого количества коротких тасков

Executorts.newSingleThreadExecutor();

Executorts.newScheduledThreadExecutor();

Часто, когда мы сабмитим таску в executor, мы не работает с абстракцией Runnable, поэтому мы не знаем, что из себя представляет эта таска, и любой RuntimeException может привести к тому, что мы "потеряем поток". Поэтому лучше сабмитить таски, внутри try catch finally блока. Например Swing использует эту технику, для запуска "неизвестного" кода, который пишут пользователя. Если бы все свинговое приложение загибалось из-за NullPointerException из-за кривого кода пользователя, это было б не очень хорошо.

	public void run() {
		Throwable thrown = null;
		try {
			while (!isInterrupted()) {
				runTask(getTaskFromWorkQueue());
			}
		} catch (Throwable e) {
			thrown = e;
		} finally {
			threadExited(this, thrown);
		}
	}


Еще есть такой интерфейс как UncaughtExceptionHandler, который можно указать при создании ThreadPoolExecutor, если он не указан, что вылетании Runtime исключения, ошибка просто выводится на консоль, интерфейс позволяет переписать это поведение

Комментариев нет:

Отправить комментарий