Пул потоков может выполнять несколько задач одновременно. Иногда мы можем отслеживать результаты выполнения задач. Даже в течение определенного периода времени, если задача не выполнена, мы также можем отменить выполнение задач. Чтобы поддержать эту функцию, ThreadPoolexeCutor предоставляет FutureTask для отслеживания выполнения и отмены задач. Эта статья представляет принцип реализации FutureTask.
Чтобы лучше понять принцип реализации FutureTask, мы сначала предоставляем несколько важных интерфейсов и структур классов, как показано на рисунке ниже:
ThreadPoolexeCutor предоставляет интерфейс отправки для отправки задач. Отправить поддерживает два разных интерфейса: запускаемые и вызывая. Чтобы предоставить унифицированный внешний интерфейс, JDK внутренне обертывает, заполненную в вызов, все из которых реализуются через адаптер RunnableAdapter. Ниже приведен исходный код RunnableAdapter:
Static Final Class RunnableAdapter <t> реализует Callable <t> {окончательный выполнение задания; окончательный результат T; RunnableAdapter (Runnable Task, t result) {this.task = task; this.Result = результат; } public t call () {task.run (); результат возврата; }}RunnableAdapter - это класс реализации Callable, который реализует метод вызова. Метод вызова просто вызывает task.run (), а затем возвращает результат, который гарантирует, что только с каллируемым интерфейсом необходимо обработать равномерно внутри.
Через предыдущий раздел мы знаем, что представленная выполняемая задача внутренне преобразуется в задачи вызова. Проверьте возвращаемое значение метода отправки, которое является будущим. На самом деле, это будущее является экземпляром FutureTask. В этом случае вызов метода GET может заблокировать текущий поток до тех пор, пока задача не будет выполнена, и результат не будет возвращен.
Вся цепочка вызовов выглядит так:
Worker Thread -> FutureTask.Run () -> callable.call () -> task.run ()
Если представлена задача, есть только первые три вызова.
Чтобы лучше продемонстрировать весь процесс, для демонстрации процесса выполнения будут использоваться следующие примеры.
1. Отправьте задачу в пул потока (запустить также будет преобразована в Callable). В настоящее время вызов передается в экземпляр FutureTask, как показано ниже:
2. Пул потоков использует поток для выполнения задачи FutureTask.
Процесс выполнения задач относительно прост. В конце концов, будет вызван метод callable.call () или runnable.run (), и будет получен результат, который будет хранить результат в свойство результата экземпляра FutureTask, и статус будет изменен в норме, что указывает на то, что задача была выполнена и результат может быть получен.
Мы предполагаем, что несколько потоков вызывают метод получить метод одного и того же экземпляра FutureTask во время выполнения callable.call() . В настоящее время эти потоки будут заблокированы и хранятся в стеке, как показано на рисунке ниже:
Потоки 1, 2 и 3 вызовите метод FutureTask.get . Поскольку задача не была выполнена, все три потока будут заблокированы и сольными. В FutureTask есть стек для хранения ожидающих потоков. На верхнем указателе стека ссылается FutureTask.waiters . Когда задача выполнена, потоки во всем стеке будут выполнены. В настоящее время каждый поток будет пробужден, и результат выполнения задачи может быть успешно получен (результат выполнения сохраняется в FutureTask.outcome) .
FutureTask также поддерживает функцию отмены задач, все из которых координируют несколько потоков через состояние FutureTask.
Интерфейс FutureTask - это механизм реализации, который предоставляет нам отслеживание и управление выполнением задач. По сравнению с самим пулом потоков это относительно просто, и я считаю, что это нетрудно понять.
Выше приведено все содержание этой статьи о принципе реализации FutureTask в пуле Java Thread. Я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на другие связанные темы на этом сайте. Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!