CountDownLatch是JAVA提供在java.util.concurrent包下的一个辅助类,可以把它看成是一个计数器,其内部维护着一个count计数,只不过对这个计数器的操作都是原子操作,同时只能有一个线程去操作这个计数器,CountDownLatch通过构造函数传入一个初始计数值,调用者可以通过调用CounDownLatch对象的cutDown()方法,来使计数减1;如果调用对象上的await()方法,那么调用者就会一直阻塞在这里,直到别人通过cutDown方法,将计数减到0,才可以继续执行。
利用这种性质可以做一些事情
简单举几种简单的例子
1.需要开多线程执行,等所有的执行完成之后。在做其他的事情。
2.某个线程执行的时间不确定,我想等5秒之后如果,如果线程还没执行完,处理其他的逻辑
1.需要开多线程执行,等所有的执行完成之后。在做其他的事情。
第一种可以模拟,赛跑比赛,每个运动员是一个线程。所有的线程到达终点比赛结束。
import java.util.concurrent.CountDownLatch;
public class Sample {
/**
* 计数器,用来控制线程
* 传入参数2,表示计数器计数为2
*/
private final static CountDownLatch mCountDownLatch = new CountDownLatch(2);
/**
* 示例工作线程类
*/
private static class WorkingThread extends Thread {
private final String mThreadName;
private final int mSleepTime;
public WorkingThread(String name, int sleepTime) {
mThreadName = name;
mSleepTime = sleepTime;
}
@Override
public void run() {
System.out.println("[" + mThreadName + "] started!");
try {
Thread.sleep(mSleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
mCountDownLatch.countDown();
System.out.println("[" + mThreadName + "] end!");
}
}
/**
* 示例线程类
*/
private static class SampleThread extends Thread {
@Override
public void run() {
System.out.println("[SampleThread] started!");
try {
// 会阻塞在这里等待 mCountDownLatch 里的count变为0;
// 也就是等待另外的WorkingThread调用countDown()
mCountDownLatch.await();
} catch (InterruptedException e) {
}
System.out.println("[SampleThread] end!");
}
}
public static void main(String[] args) throws Exception {
// 最先run SampleThread
new SampleThread().start();
// 运行两个工作线程
// 工作线程1运行5秒
new WorkingThread("WorkingThread1", 5000).start();
// 工作线程2运行2秒
new WorkingThread("WorkingThread2", 2000).start();
}
}
结果如下
[SampleThread] started!
[WorkingThread1] started!
[WorkingThread2] started!
[WorkingThread2] end!
[WorkingThread1] end!
[SampleThread] end!
2.某个线程执行的时间不确定,我想等2秒之后如果,如果线程还没执行完,处理其他的逻辑
final CountDownLatch latch = new CountDownLatch(1);
final File outFile = new File(dir, imageName);
reuslt.path=outFile.getAbsolutePath();
reuslt.bitmap=bitmap;
Thread sleepThread = new Thread() {
@Override
public void run() {
super.run();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
reuslt.result=false;
reuslt.type=Reuslt.THREAD_SLEEP;
latch.countDown();
}
};
Thread saveThread = new Thread() {
@Override
public void run() {
super.run();
boolean result=BitmapUtils.saveBitmapWithQuality(bitmap, outFile.getPath(), picQuality);
reuslt.result=result;
reuslt.type=Reuslt.THREAD_SAVE;
latch.countDown();
}
};
sleepThread.start();
saveThread.start();
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
//TODO samethings
public static List<List<ProcessInfo>> getRunningProcessListTheadPool(final Context context) {
if (DEBUG) {
Log.i(TAG, "getRunningProcessListTheadPool");
}
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
final PackageManager packageManager=context.getPackageManager();
long time = 0l;
if (DEBUG) {
time = System.currentTimeMillis();
}
final CopyOnWriteArrayList<ProcessInfo> processList = new CopyOnWriteArrayList<ProcessInfo>();
final ArrayList<ProcessInfo> whiteListProcess = new ArrayList<ProcessInfo>();
List<List<ProcessInfo>> returnList = new ArrayList<List<ProcessInfo>>();
returnList.add(processList);
returnList.add(whiteListProcess);
List<RunningAppProcessInfo> allRunningProcessesList = null;
try {
allRunningProcessesList = activityManager.getRunningAppProcesses();
} catch (Exception e) {
if (DEBUG) {
Log.e(TAG, "系统出错 ActivityManager.getRunningAppProcesses Exception");
}
}
//5.0以上有部分手机getRunningAppProcesses只能获得当前运行的自己的程序
if (!BoostRunningProcessUtil.isRunningAppProcessesEnable(allRunningProcessesList)) {
allRunningProcessesList = GetRunningProcessUtil.getRunningAppProcesses(activityManager, packageManager);
if (DEBUG) {
Log.e(TAG, "5.0以上有部分手机 打印获取的程序列表" );
for(RunningAppProcessInfo item:allRunningProcessesList){
Log.i(TAG,item.processName);
}
Log.e(TAG, "5.0以上有部分手机getRunningAppProcesses只能获得当前运行的自己的程序=");
}
}
if (allRunningProcessesList == null || allRunningProcessesList.isEmpty()) {
return returnList;
}
List<RunningServiceInfo> runningServicesTemp = null;
try {
runningServicesTemp = activityManager.getRunningServices(500);
} catch (Exception e) {
//java.lang.NullPointerException: Attempt to read from field
//'android.content.ComponentName com.android.server.am.ServiceRecord.name' on a null object reference
//at android.os.Parcel.readException(Parcel.java:1546)
//at android.os.Parcel.readException(Parcel.java:1493)
// at android.app.ActivityManagerProxy.getServices(ActivityManagerNative.java:3068)
if (DEBUG) {
Log.e(TAG, "系统出错 ActivityManager.getRunningServices Exception");
}
}
if (runningServicesTemp == null) {
runningServicesTemp = new ArrayList<RunningServiceInfo>(0);
}else{
if (DEBUG) {
Log.e(TAG, "获取到的运行的service size"+runningServicesTemp.size() );
for(RunningServiceInfo item:runningServicesTemp){
Log.i(TAG,item.process);
}
}
}
final List<RunningServiceInfo> runningServices = runningServicesTemp;
int size = allRunningProcessesList.size();
// 开始的倒数锁
final CountDownLatch begin = new CountDownLatch(1);
// 结束的倒数锁
final CountDownLatch end = new CountDownLatch(size);
final ExecutorService exec = BoosterExecutorsPro.newFixedThreadPool("getRunningProcessListTheadPool",6);
final List<String> mobiProducts = Arrays.asList(SysClearEnv.MOBIMAGICP_PRD);
final String myPkg=context.getPackageName();
for (RunningAppProcessInfo item : allRunningProcessesList) {
//////////////////////////////////////////////////////////////////////
final RunningAppProcessInfo runningAppProcessInfo = item;
Runnable run = new Runnable() {
public void run() {
try {
// 等待.如果当前计数为零,则此方法立即返回。
begin.await();
/*********************************************************************************/
if (runningAppProcessInfo == null) {
return;
}
final String processName = runningAppProcessInfo.processName;
if (TextUtils.isEmpty(processName)) {
return;
}
long singleStartTime = 0;
if (DEBUG) {
singleStartTime = System.currentTimeMillis();
Log.d(TAG, processName + " " + Arrays.toString(runningAppProcessInfo.pkgList)
+ " importance:" + runningAppProcessInfo.importance);
}
// 获取进程相关的服务
String[] processServices = LoadProcessUtils.getProcessServices(processName, runningServices);
/*
* 由于 Android 系统中一个进程可能是由多个不同的包共享的,试过把这些包都显示出来,发现比如说设置的进程,里面包含了
* Status Bar,
* 设置,设置存储三个包,它们的图标都一样,用户就会提出疑问说为什么有三个一样的,没办法,后面就只显示其中一个包
* 进程中如果没有package,则默认可杀
*/
String[] packageList = (runningAppProcessInfo.pkgList == null) ? new String[] { processName }
: runningAppProcessInfo.pkgList;
//根据PackageName处理
for (String packageName : packageList) {
long time = System.currentTimeMillis();
PackageInfo packageInfo = null;
try {
if (SysClearEnv.PACKAGE_CACHE) {
packageInfo = getPackageInfo(packageManager, packageName);
} else {
packageInfo = packageManager.getPackageInfo(packageName, 0);
}
if (packageInfo != null) {
if (!TextUtils.isEmpty(packageInfo.sharedUserId)) {
flag = ConfigLoader.getInstance(context).queryFilter(
ConfigLoader.SHARED_USER_ID, packageInfo.sharedUserId);
}
}
} catch (Exception e) {
//NameNotFoundException, Package manager has died
if (DEBUG) {
Log.e(TAG, "getPackageInfo", e);
}
}
ProcessInfo processInfo = LoadProcessUtils.createProcessInfo(context, packageInfo,
runningAppProcessInfo, packageName, processName, processServices);
// 当应用有多个进程时,将每个进程内存累加;
boolean unAddFlag = true;
synchronized (processList) {
for (ProcessInfo existProcessInfo : processList) {
if (packageName.equals(existProcessInfo.packageName)) {
// 取最小的一个进程importance作为合并进程的importance// 修正读到的flag被合并后消失的情况// 合并服务// 合并PID
unAddFlag = false;
break;
}
}
if (unAddFlag) {
processList.add(processInfo);
}
}
}
/*********************************************************************************/
} catch (Exception e) {
if (DEBUG) {
Log.e(TAG, "====getRunningProcessList有误!!!!====", e);
}
} finally {
// 每个 线程执行完成end就减一
end.countDown();
}
}
};
exec.submit(run);
//////////////////////////////////////////////////////////////////////
}
// begin减一
begin.countDown();
// 等待结束
try {
end.await();
} catch (Exception e) {
}
exec.shutdown();
return returnList;
}