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. Luogu 3942 将军令

    之前写那个(Luogu 2279) [HNOI2003]消防局的设立的时候暴力推了一个树形dp,然后就导致这个题不太会写. 贪心,先把树建出来,然后考虑按照结点深度排个序,每次取出还没有被覆盖掉的深度 ...

  2. Android开发环境搭建及HelloWorld

    在开始Android开发之旅启动之前,首先要搭建环境,然后创建一个简单的HelloWorld.本文的主题如下: 1.环境搭建 1.1.JDK安装 1.2.Eclipse安装 1.3.Android S ...

  3. MVC中使用代码创建数据库(code first +mysql+EF)

    1.新建一个mvc项目 2.安装mysql需要的几个文件 EntityFramework.MySql.Data(6.9.12)和MySql.Data.Entity (6.9.12) 这里有几点要注意 ...

  4. JavaScript知识体系索引

    JavaScript 参考手册 www.w3school.com.cn JavaScript基础语法 JavaScript的数据类型 Javascript的对象分类 JavaScript内置对象 Ja ...

  5. ASP.NET网页动态添加数据行

    一看到这标题<ASP.NET网页动态添加数据行>,想起来似乎有点难实现.因为网页的周期性原因,往往在PostBack之后,状态难于有所保留.但Insus.NET又想实现这样的效果,用户点击 ...

  6. Vue Study [2]: Vue Router

    Description The article for vue router. Original post link:https://www.cnblogs.com/markjiang7m2/p/10 ...

  7. LinkExtractor 构造器各参数说明

    LinkExtractor 构造器各参数说明 特例: LinkExtractor构造器的所有参数都有默认值 各参数说明: allow 接收一个正则表达式或一个正则表达式列表,提取绝对url与正则表达式 ...

  8. 装饰器设计模式初探及Java中实际应用举例

    本篇随笔主要介绍用Java实现简单的装饰器设计模式: 先来看一下装饰器设计模式的类图:  从图中可以看到,我们可以装饰Component接口的任何实现类,而这些实现类也包括了装饰器本身,装饰器本身也可 ...

  9. Hbase0.98.0完全分布式搭建---【使用外部zookeeper】

    Hbase是一个分布式的实时数据库,他可以基于hadoop的hdfs,S3等分布式存储系统.而且使用zookeeper来通信(查询元数据和获取数据所在位置等功能) 本文的Hbase使用的是hadoop ...

  10. 使用instsrv.exe和srvany.exe将应用程序安装成windows后台服务

    好的参考链接: http://www.jb51.net/softjc/374631.html 利用这两个工具,将 exe程序或者 bat文件,做成Windows后台服务.