Если вам нужен только этот фреймворк, можете сразу посмотреть ниже.
Если вы хотите глубже понять, как этот фреймворк реализуется шаг за шагом, от получения требований до каждого этапа размышлений, почему каждый класс спроектирован именно так, и почему существуют эти методы, то есть как разработать этот фреймворк с нуля, автор открыл специальный раздел на CSDN (https://blog.csdn.net/tianyaleixiaowu/category_9637010.html), где подробно рассказывается о разработке промежуточного программного обеспечения, включая, но не ограничиваясь этим небольшим фреймворком. Коллеги из JD могут также искать информацию об ERP на CF.
Коллеги из JD используют следующий maven для ссылки:
<dependency>
<groupId>com.jd.platform</groupId>
<artifactId>asyncTool</artifactId>
<version>1.4.2-SNAPSHOT</version>
</dependency>
Для внешних пользователей рекомендуется использовать пакет, собранный на jitpack.io: Сначала добавьте узел repositories:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
Затем добавьте следующую зависимость maven:
<dependency>
<groupId>com.gitee.jd-platform-opensource</groupId>
<artifactId>asyncTool</artifactId>
<version>V1.4-SNAPSHOT</version>
</dependency>
worker: это наименьшая единица выполнения задачи. Обычно это сетевой вызов или длительная операция.
T и V — два универсальных типа, которые представляют тип входных и выходных данных соответственно. Например, если эта длительная операция имеет входные данные String и результат Integer после завершения, можно использовать универсальные типы для определения. Между различными workers нет связи, и они могут иметь разные типы входных и выходных данных.
/**
* 每个 наименьший блок выполнения должен реализовывать этот интерфейс
* @author wuweifeng написал 2019-11-19.
*/
public interface IWorker<T, V> {
/**
* Выполните длительную операцию здесь, например, rpc-запрос или IO
*
* @param object
* объект
*/
V action(T object, Map<String, WorkerWrapper> allWrappers);
/**
* Возвращает значение по умолчанию при тайм-ауте или ошибке
* @return значение по умолчанию
*/
V defaultValue();
}
callBack: это обратный вызов для каждого worker. После завершения выполнения worker вызовет этот интерфейс с результатами успеха или неудачи, исходными входными данными и подробными результатами.
/**
* Каждый блок выполнения вызывает этот интерфейс после завершения
* Те, кто хочет отслеживать результаты выполнения, должны реализовать этот интерфейс
* @author wuweifeng написал 2019-11-19.
*/
public interface ICallback<T, V> {
void begin();
/**
* Операция с длительным временем выполнения завершена, и значение будет введено в значение
*
*/
void result(boolean success, T param, WorkResult<V> workResult);
}
wrapper: объединяет worker и callback, является наименьшей единицей планирования. Путем организации взаимосвязи между оболочками достигается цель упорядочивания различных рабочих блоков.
Универсальные типы оболочки такие же, как и у worker, что определяет типы ввода и вывода.
Например:
0 выполняется одновременно с 1 и 2, а 1\2 завершаются одновременно, затем выполняется 3. 3 будет ждать завершения 2. В это время вы можете определить worker:
/**
* @author wuweifeng написал 2019-11-20.
*/
public class ParWorker1 implements IWorker<String, String>, ICallback<String, String> {
@Override
public String action(String object) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "result = " + SystemClock.now() + "---param = " + object + " from 1";
}
@Override
public String defaultValue() {
return "worker1--default";
}
@Override
public void begin() {
//System.out.println(Thread.currentThread().getName() + "- start --" + System.currentTimeMillis());
}
@Override
public void result(boolean success, String param, WorkResult<String> workResult) {
if (success) {
System.out.println("callback worker1 success--" + SystemClock.now() + "----" + workResult.getResult()
+ "-threadName:" +Thread.currentThread().getName());
} else {
System.err.println("callback worker1 failure--" + SystemClock.now() + "----" + workResult.getResult()
+ "-threadName:" +Thread.currentThread().getName());
}}
}
Через этот класс вы можете видеть, что действие внутри представляет собой вашу длительную операцию, начало — это обратный вызов при запуске задачи, результат — это обратный вызов после завершения worker. Когда вы объединяете несколько блоков выполнения, каждый шаг находится под вашим контролем. Если произойдет сбой, будет предоставлено настраиваемое значение по умолчанию. Это невозможно сделать с помощью CompleteableFuture.
Код небольшой, просто скопируйте пакет.
ParWorker w = new ParWorker();
ParWorker1 w1 = new ParWorker1();
ParWorker2 w2 = new ParWorker2();
WorkerWrapper<String, String> workerWrapper2 = new WorkerWrapper.Builder<String, String>()
``` ```
.worker(w2)
.callback(w2)
.param("2")
.build();
WorkerWrapper<String, String> workerWrapper1 = new WorkerWrapper.Builder<String, String>()
.worker(w1)
.callback(w1)
.param("1")
.build();
WorkerWrapper<String, String> workerWrapper = new WorkerWrapper.Builder<String, String>()
.worker(w)
.callback(w)
.param("0")
.build();
long now = SystemClock.now();
System.out.println("begin-" + now);
Async.beginWork(1500, workerWrapper, workerWrapper1, workerWrapper2);
// Async.beginWork(800, workerWrapper, workerWrapper1, workerWrapper2);
// Async.beginWork(1000, workerWrapper, workerWrapper1, workerWrapper2);
System.out.println("end-" + SystemClock.now());
System.err.println("cost-" + (SystemClock.now() - now));
System.out.println(Async.getThreadCount());
System.out.println(workerWrapper.getWorkResult());
Async.shutDown();
ParWorker w = new ParWorker();
ParWorker1 w1 = new ParWorker1();
ParWorker2 w2 = new ParWorker2();
ParWorker3 w3 = new ParWorker3();
WorkerWrapper<String, String> workerWrapper3 = new WorkerWrapper.Builder<String, String>()
.worker(w3)
.callback(w3)
.param("3")
.build();
WorkerWrapper<String, String> workerWrapper2 = new WorkerWrapper.Builder<String, String>()
.worker(w2)
.callback(w2)
.param("2")
.next(workerWrapper3)
.build();
WorkerWrapper<String, String> workerWrapper1 = new WorkerWrapper.Builder<String, String>()
.worker(w1)
.callback(w1)
.param("1")
.next(workerWrapper3)
.build();
WorkerWrapper<String, String> workerWrapper = new WorkerWrapper.Builder<String, String>()
.worker(w)
.callback(w)
.param("0")
.next(workerWrapper1, workerWrapper2)
.build();
long now = SystemClock.now();
System.out.println("begin-" + now);
Async.beginWork(3100, workerWrapper);
// Async.beginWork(2100, workerWrapper);
System.out.println("end-" + SystemClock.now());
System.err.println("cost-" + (SystemClock.now() - now));
System.out.println(Async.getThreadCount());
Async.shutDown();
``` Зависимость от результатов выполнения других worker-ов в качестве входных параметров.
Можно получить результат выполнения любого блока по его идентификатору из параметров action, но необходимо учитывать порядок выполнения: если блок ещё не был выполнен, вызов WorkerResult.getResult() вернёт null!
Другие подробности см. в тестовых классах в пакете test. Поддерживаются различные комбинации и последовательности.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )