CountDownLatch简介
- countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。 是通过一个计数器来实现的,计数器的初始值是线程的数量。
- 每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。
常用API
//构建计数器实例
public CountDownLatch(int count);
//挂起线程,直到count值为0才继续执行
public void await() throws InterruptedException;
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException;
//计数器-1
public void countDown();
使用场景
1.将异步任务变成同步
场景一:变同步
- 前提:子线程执行的代码
//实例代码
//构建
CountDownLatch latch = new CountDownLatch(1);
//耗时操作,执行完毕 调用latch.countDown()即可;
T result = onExecute(latch);
try {
latch.await();
} catch (Exception e) {
}
return result;
场景二:异步任务回调
- 简单封装
public interface OnExecuteListeren<T> {
/**
* 任务执行子线回调
* @param latch
*/
T onExecute(CountDownLatch latch);
/**
* 任务结束主线程回调
*/
void onEnd(T t);
}
/**
* 异步任务变同步回调结束
* @param onExecuteListeren
*/
public static <T> void synTask(final OnExecuteListeren<T> onExecuteListeren) {
new Thread(new Runnable() {
@Override
public void run() {
CountDownLatch latch = new CountDownLatch(1);
T t = null;
if (null != onExecuteListeren) {
//任务执行完毕 需手动调用latch.countDown()即可;
t = onExecuteListeren.onExecute(latch);
}
try {
latch.await();
} catch (Exception e) {
}
if (null != onExecuteListeren) {
onExecuteListeren.onEnd(result);
}
}
}).start();
}
- 使用示例
//需求:ui线程保存一张图片,完成后返回是成功。
// 分析:启子线程保存图片。
SynUtil.synTask(new SynUtil.OnExecuteListeren<Boolean>() {
@Override
public Boolean onExecute(CountDownLatch latch) {
boolean flag = false;
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(saveFile);
fileOutputStream.write(data);
flag = true;
} catch (IOException e) {
LogUtil.e(TAG, e);
} finally {
try {
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
latch.countDown();
return flag;
}
}
@Override
public void onEnd(Boolean aBoolean) {
if (null != resultBack) resultBack.onResult(aBoolean);
}
});