Java 链接一系列异步调用
我有一系列异步操作Java 链接一系列异步调用,java,asynchronous,Java,Asynchronous,我有一系列异步操作 private void doSomething(){ get("/something", new Callback(){ void onComplete(String data){ updateUi(something, data); doSomethingElse(); } }); } private void doSomethingElse(){ get("/something/else", n
private void doSomething(){
get("/something", new Callback(){
void onComplete(String data){
updateUi(something, data);
doSomethingElse();
}
});
}
private void doSomethingElse(){
get("/something/else", new Callback(){
void onComplete(String data){
updateUi(somethingElse, data);
doYetAnotherThing();
}
});
}
private void doYetAnotherThing(){
get("/yet/another/thing", new Callback(){
void onComplete(String data){
updateUi(yetAnotherThing, data);
allDone();
}
});
}
这有几个问题:
ExecuterService#invokeAll
-我不知道如何在不阻塞的情况下使用此解决方案ListenableFutures
及其transform
方法。我在interwebs的一些地方看到了这一点,老实说,我不认为这能解决我的问题所以,问题是:在Java中链接一系列异步调用的好模式是什么?寻找一个能与Java 7一起工作的解决方案,因为我需要一个Android应用程序。自发的想法:您可以将链接调用定义为一个方法参数,以使您的方法可重用。下面是我的示例代码:
public class Scribble {
final Callback step1 = new Callback() {
void onComplete(String string) {
doSomethingElse(step2);
};
};
final Callback step2 = new Callback() {
void onComplete(String string) {
doYetAnotherThing(step3);
};
};
final Callback step3 = new Callback() {
void onComplete(String string) {
allDone();
}
};
private void start() {
doSomething(step1);
}
private void doSomething(final Callback externalCallback) {
get("/something", new Callback() {
void onComplete(String data) {
updateUi(something, data);
externalCallback.onComplete(data);
}
});
}
private void doSomethingElse(final Callback externalCallback) {
get("/something/else", new Callback() {
void onComplete(String data) {
updateUi(somethingElse, data);
externalCallback.onComplete(data);
}
});
}
private void doYetAnotherThing(final Callback externalCallback) {
get("/yet/another/thing", new Callback() {
void onComplete(String data) {
updateUi(yetAnotherThing, data);
externalCallback.onComplete(data);
}
});
}
// - the code below is only to make everything compilable -
public class Callback {
void onComplete(String string) {
}
}
private Object something;
protected Object somethingElse;
protected Object yetAnotherThing;
protected void allDone() {
System.out.println("Scribble.allDone()");
}
protected void updateUi(Object yetAnotherThing2, String data) {
System.out.println("Scribble.updateUi()"+data);
}
private void get(String string, Callback callback) {
System.out.println("get "+string);
callback.onComplete(string);
}
public static void main(String[] args) {
new Scribble().start();
}
}
关于您遇到这个问题的实际意图和用例,肯定有一些猜测。此外,还不完全清楚什么是
某物
,某物
和是另一物
(它们来自哪里,应该去哪里)
但是,根据您提供的信息,并且作为对的补充(或者更确切地说是扩展或泛化):您在那里绘制的这些伪调用之间的差异似乎是
- 传递给
方法的get
参数String
- 调用的
回调
- 下一步执行哪个方法
字符串
参数和回调
可以作为参数传递给创建可调用
的常规方法。调用的顺序可以简单地通过将这些Callable
对象以适当的顺序放入一个列表中来定义,并使用单线程执行器服务执行它们
正如您在本例的main
方法中所看到的,调用序列可以很容易地配置:
import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ChainedAsyncTest {
public static void main(String[] args) throws InterruptedException {
ChainedAsyncTest t = new ChainedAsyncTest();
ExecutorService e = Executors.newFixedThreadPool(1);
e.invokeAll(Arrays.asList(
t.call("/something", t.somethingCallback),
t.call("/something/else", t.somethingElseCallback),
t.call("/yet/another/thing", t.yetAnotherThingCallback),
t.allDone()));
}
private Callback somethingCallback = new Callback() {
@Override
public void onComplete(String data) {
updateUi("something", data);
}
};
private Callback somethingElseCallback = new Callback() {
@Override
public void onComplete(String data) {
updateUi("somethingElse", data);
}
};
private Callback yetAnotherThingCallback = new Callback() {
@Override
public void onComplete(String data) {
updateUi("yetAnotherThing", data);
}
};
private Callable<Void> call(
final String key, final Callback callback) {
return new Callable<Void>() {
@Override
public Void call() {
get(key, callback);
return null;
}
};
}
private Callable<Void> allDone() {
return new Callable<Void>() {
@Override
public Void call() {
System.out.println("allDone");
return null;
}
};
}
interface Callback
{
void onComplete(String data);
}
private void get(String string, Callback callback) {
System.out.println("Get "+string);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
callback.onComplete("result of "+string);
}
private void updateUi(String string, String data) {
System.out.println("UpdateUI of "+string+" with "+data);
}
}
导入java.util.array;
导入java.util.concurrent.Callable;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
公共类链式同步测试{
公共静态void main(字符串[]args)引发InterruptedException{
ChainedAsyncTest t=新的ChainedAsyncTest();
ExecutorService e=Executors.newFixedThreadPool(1);
e、 invokeAll(Arrays.asList(
t、 调用(“/something”,t.something callback),
t、 调用(“/something/else”,t.somethingelescallback),
t、 call(“/yet/other/thing”,t.yetAnotherThingCallback),
t、 allDone());
}
私有回调somethingCallback=new Callback(){
@凌驾
公共void onComplete(字符串数据){
更新(“某物”,数据);
}
};
私有回调somethingElseCallback=new Callback(){
@凌驾
公共void onComplete(字符串数据){
更新(“somethingElse”,数据);
}
};
私有回调yetAnotherThingCallback=新回调(){
@凌驾
公共void onComplete(字符串数据){
updateUi(“yetAnotherThing”,数据);
}
};
私人呼叫(
最终字符串键,最终回调){
返回新的可调用(){
@凌驾
公开作废通知(){
get(key,callback);
返回null;
}
};
}
私有可调用的allDone(){
返回新的可调用(){
@凌驾
公开作废通知(){
System.out.println(“全部完成”);
返回null;
}
};
}
接口回调
{
void onComplete(字符串数据);
}
私有void get(字符串、回调){
System.out.println(“Get”+字符串);
试一试{
睡眠(500);
}捕捉(中断异常e){
e、 printStackTrace();
}
callback.onComplete(“结果”+字符串);
}
私有void updateUi(字符串、字符串数据){
System.out.println(“用“+数据”更新“+字符串+”);
}
}
(本例使用了
invokeAll
,它会一直阻塞,直到所有任务都已执行。这可以通过不同的方式解决,在调用站点实现真正的非阻塞。其主要思想是创建一个任务列表,所有任务都是通过相同的方法调用创建的)我完全支持批准的答案,但我也在讨论我为这些类型的问题创建的东西,当您开始在异步操作链中添加条件逻辑时,这些问题会派上用场。我最近将其发酵成一个简单的库()
下面是您如何连接示例的。如您所见,每个任务都不知道接下来的任务。与批准的答案相反,任务的链接是通过一个简单的同步(…外观)方法体而不是列表来完成的
public void doChainedLogic() {
final AsyncTask<Void, Void> doSomething = new AsyncTask<Void, Void>() {
@Override
public void run(Void arg, final ResultHandler<Void> resultHandler) {
get("/something", new Callback() {
public void onComplete(String data) {
updateUi(something, data);
resultHandler.reportComplete();
}
});
}
};
final AsyncTask<Void, Void> doSomethingElse = new AsyncTask<Void, Void>() {
@Override
public void run(Void arg, final ResultHandler<Void> resultHandler) {
get("/something/else", new Callback() {
public void onComplete(String data) {
updateUi(somethingElse, data);
resultHandler.reportComplete();
}
});
}
};
final AsyncTask<Void, Void> doYetAnotherThing = new AsyncTask<Void, Void>() {
@Override
public void run(Void arg, final ResultHandler<Void> resultHandler) {
get("/yet/another/thing", new Callback() {
public void onComplete(String data) {
updateUi(yetAnotherThing, data);
resultHandler.reportComplete();
}
});
}
};
// This looks synchronous, but behind the scenes JasyncDriver is
// re-executing the body and skipping items already executed.
final JasyncDriver driver = new JasyncDriver();
driver.execute(new DriverBody() {
public void run() {
driver.execute(doSomething);
driver.execute(doSomethingElse);
driver.execute(doYetAnotherThing);
}
});
}
public void docainedlogic(){
final AsyncTask doSomething=new AsyncTask(){
@凌驾
公共作废运行(作废参数,最终结果删除器结果删除器){
获取(“/something”,新回调(){
公共void onComplete(字符串数据){
更新(某物、数据);
resultHandler.reportComplete();
}
});
}
};
final AsyncTask doSomethingElse=new AsyncTask(){
@凌驾
公共作废运行(作废参数,最终结果删除器结果删除器){
获取(“/something/else”,新回调(){
final AsyncTask<Void, String> checkSomething = new AsyncTask<Void, String>() {
@Override
public void run(Void arg, final ResultHandler<String> resultHandler) {
get("/check/something", new Callback() {
public void onComplete(String data) {
resultHandler.reportComplete(data);
}
});
}
};
final JasyncDriver driver = new JasyncDriver();
driver.execute(new DriverBody() {
public void run() {
driver.execute(doSomething);
if ("foobar".equals(driver.execute(checkSomething))) {
driver.execute(doSomethingElse);
}
driver.execute(doYetAnotherThing);
}
});