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. 5.Qt model view设计模式

    Introduction to Model/View Programming       QT4 介绍了一系列新的 Item View 类,这些类使用Model/View结构来管理数据和数据如何呈现给 ...

  2. 删除GHOST中win7桌面IE删不掉的解决办法

    打开Win+R 运行regedit 依次打开: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Deskto ...

  3. 数据结构--树--AVL树

    详情查看:http://www.cnblogs.com/skywang12345/p/3577360.html

  4. 《Maven实战》笔记-7-持续集成

    一.持续集成的步骤: 1.持续编译 2.持续数据库集成 3.持续测试 4.持续审查 5.持续部署 6.持续反馈   二.持续集成工具——Hudson 1.安装Hudson 2.准备Subversion ...

  5. 基于jQuery的Tooltip

    近来,要开发一个关务管理系统,为了增加系统美观度,自己开发了一个基于jQuery框的的小插件,与大家分享一下,希望大家能给我提出宝贵修改意见. 下面开发说明使用方法和内容: 一.引用jQuery框架, ...

  6. [转]MySQL时间与字符串相互转换

    转至:https://www.cnblogs.com/wangyongwen/p/6265126.html 时间.字符串.时间戳之间的互相转换很常用,但是几乎每次使用时候都喜欢去搜索一下用法:本文整理 ...

  7. JavaScript混淆压缩

    比较好用的压缩软件,支持合并 JsCompressor-v3.0 比较好用的混淆站点:http://dean.edwards.name/packer/

  8. js 操作html dom

    author:冯永贤(Tony Feng,鸡鸣星),文章整合:internet <HTML DOM> 一:js能够改变HTML DOM 里面的什么内容 JavaScript 能够改变页面中 ...

  9. [Algorithm]栈和队列

    一.栈和队列综合(算法) 1.判断单链表(带头结点)的结点值(字符型)是否中心对称 1 bool IsSymmetry( LinkList& L ) 2 { 3 char S[MAXSIZE] ...

  10. 安卓手机牛逼软件Termux中安装Archlinux,安装Jdk

    说出来你可能不信,手机上居然装了两个linux系统,和真实的linux有些许些差别. 首先安装了Termux以后你发现,好多linux常用功能都有,什么Pyhton,gcc,g++,ruby,Php, ...