java - 领英解析。如何在任务后运行任务?
问题描述
我正在使用parseq框架进行异步计算。
考虑以下代码。它首先查询 google.com 的内容,然后将内容映射到它的长度。最后,打印长度。
问题是只运行第一个任务。为什么?
public class Main {
public static void main(String[] args) throws Exception {
OkHttpClient okHttpClient = new OkHttpClient();
final int numCores = Runtime.getRuntime().availableProcessors();
final ExecutorService taskScheduler = Executors.newFixedThreadPool(numCores + 1);
final ScheduledExecutorService timerScheduler = Executors.newScheduledThreadPool(numCores + 1);
final Engine engine = new EngineBuilder()
.setTaskExecutor(taskScheduler)
.setTimerScheduler(timerScheduler)
.build();
Task<Integer> task = Task.async(() -> {
SettablePromise<String> promise = Promises.settable();
Request request = new Request.Builder()
.url("http://google.com")
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.out.println("error");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
promise.done(response.body().string());
}
});
return promise;
}).map("map content to length", content -> content.length())
.andThen(System.out::println);
engine.blockingRun(task);
engine.blockingRun(task);
}
}
解决方案
我能够通过使用HttpClient
代替来解决您的问题OkHttp
。
以下是我用于此代码的整体 Maven 依赖项:
<dependency>
<groupId>com.linkedin.parseq</groupId>
<artifactId>parseq</artifactId>
<version>3.0.11</version>
</dependency>
<dependency>
<groupId>com.linkedin.parseq</groupId>
<artifactId>parseq-http-client</artifactId>
<version>3.0.11</version>
</dependency>
import com.linkedin.parseq.Engine;
import com.linkedin.parseq.EngineBuilder;
import com.linkedin.parseq.Task;
import com.linkedin.parseq.httpclient.HttpClient;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
public class Main {
private static Task<Integer> fetchBody(String url) {
Task<Integer> map = HttpClient.get(url).task().map("map content to length", content -> content.getResponseBody().length());
return map;
}
public static void main(String[] args) {
final int numCores = Runtime.getRuntime().availableProcessors();
final ExecutorService taskScheduler = Executors.newFixedThreadPool(numCores + 1);
final ScheduledExecutorService timerScheduler = Executors.newScheduledThreadPool(numCores + 1);
final Engine engine = new EngineBuilder()
.setTaskExecutor(taskScheduler)
.setTimerScheduler(timerScheduler)
.build();
final Task<Integer> stackOverFlow = fetchBody("http://www.stackoverflow.com");
final Task<Integer> google = fetchBody("http://www.google.com");
final Task<Integer> ethereum = fetchBody("http://ethereum.stackexchange.com");
final Task<String> plan = Task.par(stackOverFlow, google, ethereum)
.map((s, g, e) -> "StackOverFlow Page: " + s + " \n" +
"Google Page: " + g + "\n" +
"Ethereum Page: " + e + "\n")
.andThen(System.out::println);
engine.run(plan);
}
}
输出:
StackOverFlow Page: 149
Google Page: 13097
Ethereum Page: 152
这个例子是完全异步的。StackOverflow、Google 和 Ethereum 的主页都是并行获取的,而原始线程已返回到调用代码。我们使用 Tasks.par 告诉引擎并行化这些 HTTP 请求。检索到所有响应后,它们将转换为
int
最终打印出来的(字符串长度)。
要点:https ://gist.github.com/vishwaratna/26417f7467a4e827eadeee6923ddf3ae
推荐阅读
- python - 如何使用熊猫区间查找值,填充另一个数据框
- assembly - mov指令的各种编码
- javascript - 如何在可滚动中激活向下滚动按钮
- android-studio - 排查 Flutter 错误:无法加载资产
- java - Spock:测试紧耦合类
- python - 从python上的文本文件中删除字符串开头的空格
- c# - 将 XML 多个节点放入具有 2 列的 dataGridView
- python - 将 tf.contrib.layers.xavier_initializer() 更改为 2.0.0
- ios - 使用 HERO 转换更改根视图控制器
- excel - Excel 如何知道文件“在上次保存之前没有重新计算”。我可以欺骗 Excel 以相反的方式思考吗?