Сегодня мы узнаем, как выполнять асинхронное программирование весной. Мы все знаем, что потоки, которые request на обработку запросов веб -сервера получают из пула потоков, что не сложно объяснить, потому что, когда количество веб -запросов очень большое, как создать поток обработки при появлении запроса. Поскольку накладные расходы создания потоков и переключения контекста потока относительно велики, веб -сервер в конечном итоге столкнется с ударом. Кроме того, потоки обработки, созданные веб -сервером, выполняются синхронно от начала до конца по умолчанию. То есть, если обработка потока A отвечает за запрос на обработку B, то, когда B не return , обработка потока A не может сбежать для обработки других запросов, что значительно ограничит способность к параллельной обработке веб -сервера.
Следовательно, пул потоков решает проблему переработки потоков, так как решить запрос на синхронную обработку? Ответ - асинхронная обработка. Что такое асинхронная обработка? Асинхронная обработка в основном позволяет простально простояю выше B, прежде чем будет выполнена обработка вышеуказанного запроса, и резьба A может быть освобождена для продолжения обработки других запросов. Затем мы можем сделать это, перезапустить поток C в потоке A, чтобы выполнить задачу, позвольте вернуть непосредственно на веб -сервер и продолжать принимать новые запросы.
Прежде чем начать объяснение ниже, я сначала различу два понятия здесь:
1. Обработка потоков
Поток обработки принадлежит веб -серверу, отвечает за обработку запросов пользователей и управляется пулом потоков
2. Асинхронная резьба
Асинхронные потоки являются пользовательскими потоками и могут управляться пулами потоков.
Весна обеспечивает поддержку асинхронных задач. Асинхронные задачи могут быть реализованы с использованием класса WebAsyncTask . В то же время мы также можем установить соответствующую обработку обратного вызова для асинхронных задач, например, как справиться, когда задача истекло и как бросить исключение. Асинхронные задачи обычно очень практичны. Например, мы хотим оставить операцию, которая может быть обработана в течение долгого времени в асинхронном потоке для обработки, или когда заказ оплачен, мы позволяем асинхронной задаче запросить результат оплаты заказа.
1. Нормальные асинхронные задачи
Для демонстрационного удобства выполнение асинхронных задач моделируется с использованием Thread.sleep(long) . Теперь предположим, что пользователь запрашивает следующий интерфейс:
http://localhost:7000/demo/getUserWithNoThing.json
Асинхронная интерфейс задачи определяется следующим образом:
/*** Проверьте асинхронные задачи без какого -либо исключения*/@requestmapping (value = "getUserwithnothing.json", method = requestmethod.get) public webasynctask <string> getUserWithNothing () {// Печать имены нитей. // Это имитирует открытие асинхронной задачи, с временем 10S webasynctask <string> task1 = new webasynctask <string> (10 * 1000l, () -> {System.err.println («Имя первого потока -« + thread.currentthread (). GetName ());// время обработки задачи -это 5S, а не Thuthout. вернуть "Задача 1 успешно выполняется! Никаких исключений не брошено!";}); // Метод вызывается, когда выполнение задачи завершено task1.oncompletion (() -> {System.err.println ("Task 1 выполняет завершено!");}); System.err.println («Task1 продолжает справляться с другими вещами!»); вернуть задание1;}Консоль печатает следующим образом:
Основное имя потока-http-nio-7000-exec-1
Task1 продолжает иметь дело с другими вещами!
Первое имя потока - mvcasync1
Задача 1 была завершена!
Результаты браузера следующие:
2. Превышение исключительной асинхронной задачи
Интерфейс -звонок: http://localhost:7000/demo/getUserWithError.json
/*** Проверьте асинхронную задачу, в которой возникает ошибка* @return*/ @requestmapping (value = "getUserwitherRor.json", method = requestMethod.get) public webasynctask <string> getUserWitherRor () {System.err.println ("Основная нить" + Thread.currentThread (). асинхронная задача. Webasynctask <string> task3 = new webasynctask <string> (10 * 1000l, () -> {System.err.println («Второе имя потока -« + thread.currentThread (). GetName ()); // Исключение, выбрасываемое здесь int = 9/0; -> {System.err.println ("================================================================================================== ========================================================================================= ========================================================================================= ========================================================================================== "===================================================================== ======================================================================= ======================================================================= ======================================================================= ======================================================================= ======================================================================= ======================================================================= =======================================================================Выход консоли выглядит следующим образом:
Основное имя потока-http-nio-7000-exec-1
Task3 продолжает иметь дело с другими вещами!
Второе название потока - mvcasync1
2018-06-15 09: 40: 13.538 Ошибка 9168 --- [NIO-7000-EXEC-2] OACCC [.java.lang.arithmeticexception: / by Zero
на com.example.demo.controller.getuserinfocontroller.lambda $ 5 (getuserinfocontroller.java:93) ~ [Classes/: Na]
на org.springframework.web.context.request.async.webasyncmanager.lambda $ startCallableProcessing 4 долл. США (webasyncmanager.java:317) ~ [Spring-web-5.0.6.release.jar: 5.0.6.Release]
на java.util.concurrent.executors $ runnableadapter.call (experators.java:511) ~ [NA: 1.8.0_161]
на java.util.concurrent.futuretask.run (FutureTask.java:266) ~ [NA: 1.8.0_161]
на java.lang.thread.run (Thread.java:748) [NA: 1.8.0_161]2018-06-15 09: 40: 13.539 Ошибка 9168 --- [NIO-7000-EXEC-2] OACCC [. Вложенное исключение - java.lang.arithmeticexception: / по нулю] с основной причиной
java.lang.arithmeticexception: / by Zero
на com.example.demo.controller.getuserinfocontroller.lambda $ 5 (getuserinfocontroller.java:93) ~ [Classes/: Na]
на org.springframework.web.context.request.async.webasyncmanager.lambda $ startCallableProcessing 4 долл. США (webasyncmanager.java:317) ~ [Spring-web-5.0.6.release.jar: 5.0.6.Release]
на java.util.concurrent.executors $ runnableadapter.call (experators.java:511) ~ [NA: 1.8.0_161]
на java.util.concurrent.futuretask.run (FutureTask.java:266) ~ [NA: 1.8.0_161]
на java.lang.thread.run (Thread.java:748) [NA: 1.8.0_161]========================================================================================
Миссия 3 произошла!
Задача 3 была завершена!
Конечно, вы также можете выполнить некоторую обработку исключений в вышеперечисленном, чтобы избежать недружелюбного мнения пользователя. Для обработки исключений вы можете проверить еще одну статью в моей статье об использовании Spring Boot/Spring Unified Unified Samering схема обработки ошибок
Результаты вывода браузера:
3. Тайм -аут асинхронная задача
Интерфейс -звонок: http://localhost:7000/demo/getUserWithTimeOut.json
/*** Проверьте асинхронную задачу, в которой задача временем* @return*/ @requestmapping (value = "getUserwithtimeout.json", method = requestmethod.get) public webasynctask <string> getUserwithtimeout () {System.err.println ("Основная тема" - " + Thread.currentThreadThread (). // Это смоделировано, чтобы запустить асинхронную задачу, тайм -аут 10S webasynctask <string> task2 = new webasynctask <string> (10 * 1000l, () -> {System.err.println («Имя второго потока" + Thread.currentThread (). GetName ()); Thread.sleep (20 * 1000L); // тайм -аут задачи вызывает этот метод task2.ontimeout (() -> { System.err.println ("==================================================================================================== ========================================================================================== ========================================================================================== ========================================================================================== "===================================================================== ======================================================================= ======================================================================= ======================================================================= ======================================================================= ======================================================================= ======================================================================= =======================================================================Результаты выполнения консоли:
Основное имя потока-http-nio-7000-Exec-4
Task2 продолжает иметь дело с другими вещами!
Второе название потока - mvcasync2
==========================================================================================
Задача 2 была завершена!
Результаты выполнения браузера:
4. Асинхронные задачи бассейна.
Асинхронные задачи в трех вышеуказанных случаях не управляются механизмом пула потоков по умолчанию. То есть, если вступает запрос, хотя выпущен поток обработки, система все равно будет создавать асинхронную поток задачи для каждого запроса, который является асинхронным потоком задачи, начиная с MvcAsync , как мы видели выше. То есть это не сработает, накладные расходы особенно высоки! Поэтому мы можем использовать пул потоков для управления и напрямую передать экземпляр объекта ThreadPoolTaskExecutor в конструкторе класса WebAsyncTask .
Давайте сначала посмотрим, что происходит при выполнении параллельных запросов в первом случае выше (здесь мы имитируем одновременные вызовы http://localhost:7000/demo/getUserWithNoThing.json ):
Выход консоли выглядит следующим образом:
Первое имя потока - mvcasync57
Первое имя потока - mvcasync58
Первое название потока - mvcasync59
Первое имя потока - mvcasync60
Первое имя потока - mvcasync61
Первое имя потока - mvcasync62
Первое имя потока - mvcasync63
Первое имя потока - mvcasync64
Первое имя потока - mvcasync65
Первое имя потока - mvcasync66
Первое имя потока - mvcasync67
Первое имя потока - mvcasync68
Первое название потока - mvcasync69
Первое название потока - mvcasync70
Первое имя потока - mvcasync71
Первое имя потока - mvcasync72
Первое название потока - mvcasync73
Первое имя потока - mvcasync74
Первое имя потока - mvcasync76
Первое название потока - mvcasync75
Первое имя потока - mvcasync77
Первое имя потока - mvcasync78
Первое название потока - mvcasync79
Первое название потока - mvcasync80
Поскольку пул потоков не добавлен, 100 запросов откроют 100 асинхронных потоков задач, что особенно дорого и не рекомендуется.
Ниже приводится реализация пула потоков:
Интерфейс вызова: http://localhost:7000/demo/getUserWithExecutor.json
/*** Пул тестовых потоков* @return*/ @requestMapping (value = "getUserWiteExeCutor.json", method = requestMethod.get) public webasynctask <string> getUserWiteExeCutor () {System.err.println ("Основное имя потока" + Thread.currentThread (). GetName ()); // Это смоделировано, чтобы запустить асинхронную задачу, и здесь проходит пул потоков. Webasynctask <string> task1 = new webasynctask <string> (10 * 1000l, исполнитель, () -> {System.err.println («Первое имя потока -« + thread.currentThread (). GetName ()); thread.sleep (5000L); возврат «задача 4 успешно! // Вызовите этот метод, когда выполнение задачи завершено task1.oncompletion (() -> {System.err.println ("Task 4 выполняет завершено!");}); System.err.println ("Task4 продолжает справляться с другими вещами!"); вернуть задание1;}Пул потоков определяется следующим образом:
@Configurationpublic class myexecutor {@bean public static tradepooltaskexecutor getexeCutor () {threadPoolTaskexeCutor taskexeCutor = new ThreadPoolTaskexeCutor (); taskexecutor.setCorePoolsize (30); taskexecutor.setmaxpoolsize (30); taskexecutor.setqueuecapacity (50); taskexecutor.setthreadnameprefix ("huang"); // Асинхронное имя потока задачи - это префикс huang return taskexecutor; }}Одновременные тесты, выше, можно использовать для получения следующих результатов:
Пример кодового адреса этой статьи: https://github.com/smallercoder/webasynctask
Использование пулов потоков может сохранить ресурсы сервера и оптимизировать возможности обработки сервера. Не забудьте использовать их часто! Спасибо за чтение! Если вы думаете, что это будет полезно для вас, пожалуйста, начните!
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.