2017-02-12 2 views
1

Я знаю некоторые подробности относительно AbstractQueuedSynchronizer. Это структура для создания зависимых от состояния классов или синхронизатора. Но я не хочу расширять этот класс в Worker ThreadPoolExecutor.

private final class Worker extends AbstractQueuedSynchronizer implements Runnable 

Как видно подписью работника класса следующие вещи можно сделать вывод:

  1. Когда новый Runnable/Callable задача представляется, новый объект Worker создается.

  2. Новый объект Работника можно рассматривать как новую тему.

  3. addWorker() метод добавит нового рабочего (или просто задачу) и вызовет сам по себе worker.start(), чтобы начать поток.

  4. класса Worker не является статическим вложенным классом, следовательно, он может получить доступ ко всем переменному ThreadPoolExecutor

  5. run() метод класса Worker внутренне называет runWorker (это)

    общественного недействительным запуска() { runWorker (это); }

  6. runWorker() выполняет фактическую задачу что-то вроде этого:

    void runWorker(Worker w) { try { w.lock(); w.firstTask.run() } finally { w.unlock(); } }

AQS используется только для этого замка и разблокировка runWorker() метод. Не можете ли мы взять ReentrantLock здесь и оставить класс Worker простым?

Также класс предоставить документацию относительно этого, но я не могу понять, что:

Этот класс оппортунистически расширяет AbstractQueuedSynchronizer для упрощения получения и снятия блокировки, окружающую каждую задачу выполнения. Это защищает от прерываний, которые предназначены для пробуждения рабочего потока, ожидающего выполнения задачи, вместо прерывания задачи . Мы реализуем простой резервный блокирующий блокировку исключения вместо использования ReentrantLock, потому что мы не хотим, чтобы рабочие задачи могли восстановить блокировку при вызове методов управления пулами , как setCorePoolSize.

Пожалуйста, помогите

ответ

2

Ответ на ваш вопрос в цитате из javadoc которые Опубликованная:

Мы реализуем простую неповторно взаимоисключающую блокировку, а не использование ReentrantLock, потому что мы делаем не хотят, чтобы рабочие задачи были в состоянии восстановить блокировку при вызове методов управления пулами, таких как setCorePoolSize.

Это потому, что потоки, которые могут быть в ожидании задач обозначены не заперта, т.е. tryLock возвращает true для них. А что может произойти в этом случае, если ReentrantLock будет использоваться здесь: тогда можно будет следующая последовательность действий: (! Здесь успех)

setCorePoolSize - ->interruptIdleWorkers>tryLock() ->Thread.interrupt (нить этого работника)

, из-за которого рабочий прерывает себя.

Смежные вопросы