我曾经实现Runnable
接口来peek()
队列中的项目并将其发送到API。
但是现在我需要使用Callable
接口来peek()
队列并将项目发送到API。如果返回200,则从队列中删除该项目。
这是我用来实现此功能的代码。如何修改代码?有任何例子或参考吗?谢谢。
public class QueueProcessor implements Runnable{
private static ObjectQueue<JSONObject> objectQueue;
static {
objectQueue = new ObjectQueue<JSONObject>();
}
public void run() {
//add items to the queue
objectQueue.add(jsonObeject)
Random r = new Random();
try {
while (true) {
try {
if (!objectQueue.isEmpty()) {
JSONObject o = objectQueue.remove();
sendRequest(o.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
Thread.sleep(r.nextInt(DEFAULT_RANGE_FOR_SLEEP));
}
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
public void sendRequest(JSONObject json) {
Client client = ClientBuilder.newClient();
WebTarget baseTarget = client.target("someUrl");
Invocation.Builder builder = baseTarget.request();
Response response = builder.post(Entity.entity(json.toString(), MediaType.APPLICATION_JSON));
int code = response.getStatus();
if (200 == code) {
objectQueue.remove();
}
}
答案 0 :(得分:1)
只是为了入门,请参考this other SO question
并注意问题本身的第一点。
要实现异步调用,首先需要解耦-任务提交/执行(从队列中选择项目并进行API调用)和API调用后的响应处理(如果响应状态为200则从队列中删除项目)。这种去耦可以通过-ExecutorService
来实现因此,首先将ExecutorService
引入您的Runnable
代码中,即从某个使用Runnable
提交/执行的控制器类(具有main方法的类)开始执行Executor
要求。您尚未显示如何触发线程,因此您可能已经这样做了。
现在将Runnable
更改为Callable<Response>
,即创建一个类似于Runnable的Callable并实现Callable<Response>
并在call()
方法中进行API调用。您确实需要与主控制器类和该Callable类共享ObjectQueue<JSONObject>
,以便队列实现需要是线程安全的,或者需要使call()
方法是线程安全的。
我的意思是,您要么在控制器中的队列中循环,然后继续为每个项目提交请求,要么将整个队列传递给Callble,然后在此处完成抽签-这就是您的要求。
需要注意的是,到目前为止,call()
方法返回一个值-Callable,而run()
的{{1}}方法没有返回任何值,这是一个主要的两者之间的区别。
现在回到控制器类-提交或执行方法会将您的Runnable
包装到Response
submit
现在在Future上结合使用Future
和isDone()
方法,以从队列中删除该项目。
请记住,您应该能够从API响应中识别队列中的已处理对象-如果没有,则需要将API响应与已提交的get()
结合起来,并将其包装在JSONObject
中以找出哪个对象删除到。仅状态是不够的,并且如果限制队列仅删除顶部元素,则可能需要其他数据结构来容纳对象。如果仅将runnable替换为callable,但又不希望使程序真正异步,则不会出现这种复杂情况。
这些只是广泛的指导原则,提供现成的代码是我不会做的。只要您的基本知识正确,您将在Internet上找到许多示例。另外,请务必在粘贴代码时包含Future
语句。
少量链接
How to send parallel GET requests and wait for result responses?
How to send multiple asynchronous requests to different web services?