如何使用Java可调用接口异步处理队列项目?

时间:2018-10-22 04:16:13

标签: java multithreading jersey-2.0 runnable callable

我曾经实现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();
 }  

}

1 个答案:

答案 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上结合使用FutureisDone()方法,以从队列中删除该项目。

请记住,您应该能够从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?