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;
}



 

多线程编程_CountDownLatch的更多相关文章

  1. Web Worker javascript多线程编程(一)

    什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验. 一般来说Javascript ...

  2. Web Worker javascript多线程编程(二)

    Web Worker javascript多线程编程(一)中提到有两种Web Worker:专用线程dedicated web worker,以及共享线程shared web worker.不过主要讲 ...

  3. windows多线程编程实现 简单(1)

    内容:实现win32下的最基本多线程编程 使用函数: #CreateThread# 创建线程 HANDLE WINAPI CreateThread( LPSECURITY_ATTRIBUTES lpT ...

  4. Rust语言的多线程编程

    我写这篇短文的时候,正值Rust1.0发布不久,严格来说这是一门兼具C语言的执行效率和Java的开发效率的强大语言,它的所有权机制竟然让你无法写出线程不安全的代码,它是一门可以用来写操作系统的系统级语 ...

  5. windows多线程编程星球(一)

    以前在学校的时候,多线程这一部分是属于那种充满好奇但是又感觉很难掌握的部分.原因嘛我觉得是这玩意儿和编程语言无关,主要和操作系统的有关,所以这部分内容主要出现在讲原理的操作系统书的某一章,看完原理是懂 ...

  6. Java多线程编程核心技术---学习分享

    继承Thread类实现多线程 public class MyThread extends Thread { @Override public void run() { super.run(); Sys ...

  7. python多线程编程

    Python多线程编程中常用方法: 1.join()方法:如果一个线程或者在函数执行的过程中调用另一个线程,并且希望待其完成操作后才能执行,那么在调用线程的时就可以使用被调线程的join方法join( ...

  8. 浅述WinForm多线程编程与Control.Invoke的应用

    VS2008.C#3.0在WinForm开发中,我们通常不希望当窗体上点了某个按钮执行某个业务的时候,窗体就被卡死了,直到该业务执行完毕后才缓过来.一个最直接的方法便是使用多线程.多线程编程的方式在W ...

  9. Java—多线程编程

    一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程.一个线程不能独立的存 ...

随机推荐

  1. java 中一个char包含几个字节

    背景   char包含几个字节可能记得在上学的时候书上写的是2个字节,一直没有深究,今天我们来探究一下到底一个char多少个字节? Char   char在设计之初的时候被用来存储字符,可是世界上有那 ...

  2. .replace(/-/g,"/")的用法

    /-/g正则表达式   g  代表  global    全部替换 var str1 ="2012-08-12 23:13"; str1 = str1.replace(/-/g,& ...

  3. (数组)字符串的回文构词法( anagrams)

    题目:https://www.nowcoder.com/practice/e84e273b31e74427b2a977cbfe60eaf4?tpId=46&tqId=29130&tPa ...

  4. Xshell连接不上Linux的解决方法

    xshell连接linux主机时,会出现错误:Could not connect to '127.0.0.1' (port 22): Connection failed.  但是这时能ping通. 通 ...

  5. 使用metasploit进行栈溢出攻击-2

    基本的栈溢出搞明白了,真实攻击中一个很重要的问题是shellcode生成. 利用Metasploit提供的工具,可以方便的生成shellcode,然后可以使用第一篇中的代码进行验证. 先说一下如何生成 ...

  6. 转:IDEA 与 eclipse 的部分区别!

    Idea 与 Eclipse 快捷键的区别,上为Eclipse的快捷键,下为Idea的快捷键查找类名CTRL + SHIFT + RCTRL + N 查找JAR包中的类CTRL + SHIFT + T ...

  7. Kali Linux介绍篇

    Kali Linux 官网:https://www.kali.org/ Kali Linux 前身是著名渗透测试系统BackTrack ,是一个基于 Debian 的 Linux 发行版,包含很多安全 ...

  8. WP8.1&UWP手机设备对状态栏操作

    改UWP和WP8.1手机设备的状态栏.首先先说较为普遍的WP8.1设备:首先添加引用:using Windows.UI.ViewManagement;其次就可以使用StatusBar了,它提供了以下方 ...

  9. B:魔兽世界之一:备战

    描述 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部.两个司令部之间是依次排列的若干城市. 红司令部,City 1,City 2,……,City n,蓝司令部 两军的司令部都会制造武士.武士一共 ...

  10. HDU - 1166 敌兵布阵 方法一:(线段树+单点修改,区间查询和) 方法二:利用树状数组

    C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于 ...