如何在Java线程中使用异步调用循环方法



我不知道如何用内部的异步方法实现方法的循环。当我循环该方法时,它在方法内的所有异步调用完成之前递增。有什么办法处理这个吗?代码示例:

void runEngine() {
for(range) {
someAsyncCall();
}
}

void main() {
Runnable r = () -> {
runEngine();
};
while(!stop) {
Thread t1 = new Thread(r);
t1.start();
t1.setDaemon(false);
t1.join();
}
}

详细示例:

package com.abc;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
public class SomeClass{
private final OkHttpClient client = new OkHttpClient();
static void asyncCall() {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override public void onResponse(Call call, Response response) throws IOException {
try (ResponseBody responseBody = response.body()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(responseBody.string());
}
}
});
}
static void runEngine() {
for(int k = 0; k < 100; k++) {
asyncCall();
}
}

public static void main(String[] args) throws InterruptedException {
Runnable r = () -> {
runEngine();
};
while(true) {
Thread t1 = new Thread(r);
t1.start();
t1.setDaemon(false);
t1.join();
}
}
}

我用OkHttp网站上的例子替换了我的asyncCall,想法是一样的。

因此,似乎正在创建一个线程来启动不阻塞的异步任务。因此,线程在异步任务运行时完成,thread.join返回。

如果您想等待异步任务完成,可以使用CountDownLatch。

static void runEngine() throws InterruptException {
int n = 100;
CountDownLatch cdl = new CountDownLatch(n);
for(int k = 0; k < n; k++) {
asyncCall(cdl);
}
cdl.await();
}

自从您使用静态方法以来,我已经将倒计时闩锁作为一个参数。

static void asyncCall(CountDownLatch cdl) {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(Call call, IOException e) {
e.printStackTrace();
cdl.countDown();
}
@Override public void onResponse(Call call, Response response) throws IOException {
try (ResponseBody responseBody = response.body()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(responseBody.string());
} finally{
cdl.countDown();
}
}
});
}

现在提交了一大块异步任务,线程将阻塞,直到其中100个调用了CoundDownLatch.countDown()。我在finally块中倒计时,以提高任务失败时调用它的机会。还需要在onFailure中调用countDown,以确保获得足够的许可。

最新更新