Java 使用 CountDownLatch 轮询方法直到成功响应

Posted

技术标签:

【中文标题】Java 使用 CountDownLatch 轮询方法直到成功响应【英文标题】:Java Using CountDownLatch to poll a method until a success response 【发布时间】:2017-07-13 17:36:34 【问题描述】:

我试图每 60 秒多次调用一个方法,直到该方法的成功响应实际上调用了不同服务上的休息端点。截至目前,我正在使用 do while 循环并使用

Thread.sleep(60000);

让主线程等待 60 秒,由于并发问题,我觉得这不是理想的方法。

我遇到了使用 CountDownLatch 方法

CountDownLatch latch = new CountDownLatch(1);
boolean processingCompleteWithin60Second = latch.await(60, TimeUnit.SECONDS);

@Override
public void run()

    String processStat = null;
    try 
        status = getStat(processStatId);
        if("SUCCEEDED".equals(processStat))
        
            latch.countDown();
        
     catch (Exception e) 
        e.printStackTrace();
       

我在另一个实现可运行的类中有运行方法。无法使其正常工作。知道有什么问题吗?

【问题讨论】:

你为什么要调用 await 两次?你是什​​么意思'不能让这个工作?' 抱歉错误。我已经纠正了。我面临的问题是,我正在从 Runnable 类调用该方法,但无法弄清楚如何将成功/错误响应从可运行类传递到主线程。 【参考方案1】:

您可以使用CompletableFuture 而不是CountDownLatch 来返回结果:

CompletableFuture<String> future = new CompletableFuture<>();

invokeYourLogicInAnotherThread(future);

String result = future.get(); // this blocks

在另一个线程中(可能在循环中):

@Override
public void run() 

    String processStat = null;
    try 
        status = getStat(processStatId);
        if("SUCCEEDED".equals(processStat))
        
            future.complete(processStat);
        
     catch (Exception e) 
        future.completeExceptionally(e);
       

还有get()版本有超时限制:

String result = future.get(60, TimeUnit.SECONDS);

【讨论】:

项目在 Java 7 上运行。无法使用 CompletableFuture。 可以选择使用番石榴吗?我的意思是它的ListenableFuture:google.github.io/guava/releases/21.0/api/docs/com/google/common/…【参考方案2】:

终于用 Executor Framework 让它工作了。

            final int[] value = new int[1];
            pollExecutor.scheduleWithFixedDelay(new Runnable() 

                Map<String, String> statMap = null;

                @Override
                public void run() 

                    try 
                        statMap = coldService.doPoll(id);
                     catch (Exception e) 

                    
                    if (statMap != null) 
                        for (Map.Entry<String, String> entry : statMap
                                .entrySet()) 
                            if ("failed".equals(entry.getValue())) 
                                value[0] = 2;

                                pollExecutor.shutdown();
                            
                        
                    
                

            , 0, 5, TimeUnit.MINUTES);
            try 
                pollExecutor.awaitTermination(40, TimeUnit.MINUTES);
             catch (InterruptedException e) 

            

【讨论】:

以上是关于Java 使用 CountDownLatch 轮询方法直到成功响应的主要内容,如果未能解决你的问题,请参考以下文章

Java线程池主线程等待子线程的方法

Java线程池主线程等待子线程的方法

Java线程池主线程等待子线程的方法

Java并发包中CountDownLatch的工作原理使用示例

java CountDownLatch 使用介绍

Java并发编程--CountDownLatch