CountDownLatch类的用法:
今日碰到这样的问题。调用第三方sdk的方式提供的api,发现api以监听的方式异步返回结果,而我方要求提供实时数据给用户,所以这里就涉及到第三方异步接口同步调用的问题。开始的想法是以简单的while语句循环使用,但这种方式实在不优雅。经同事提点采用了JDK中提供的CountDownLatch类解决“第三方异步接口同步调用”这个问题。下面是对CountDownLatch的介绍。
CountDownLatch是一个多线之间的阻塞器,实例化时可以指定计数器的个数(这里假设为4)。通过await()进行阻塞主线程等待,然后可以调用countDown()进行计数器的递减,直到4递减为0,表示所有子线程的任务全部结束。之后被阻塞的线程才会继续往下执行。
实例代码如下
package com.dmain.test;
import java.util.concurrent.CountDownLatch;
import com.dmain.listenter.DemoListenter;
public class CountDownLatchTest {
private static String result = null;
public static void main(String[] args) throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1);
new DemoListenter("my name") {
@Override
public void getResult(String message) {
result = message;
countDownLatch.countDown();
}
@Override
public void error(String errorInfor) {
countDownLatch.countDown();
}
};
countDownLatch.await();
System.out.println("current return user:"+result);
}
}
package com.dmain.listenter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public abstract class DemoListenter {
//创建单线程池
private ExecutorService singleThread = Executors.newSingleThreadExecutor();
private String param;
public DemoListenter(){
}
public DemoListenter(String param){
this.param = param;
init();
}
protected void init(){
singleThread.execute(new Runnable(){
@Override
public void run() {
doSomething();
}
});
}
public void doSomething() {
try {
System.out.println("begin doSomething!");
String upParam = param.toUpperCase();
//这里假设处理业务要消耗一定的时间。
Thread.sleep(1200);
getResult(upParam);
System.out.println("end doSomething!");
} catch (Exception e) {
error("happen exception!");
e.printStackTrace();
}
}
public abstract void getResult(String message);
public abstract void error(String errorInfor);
}