zoukankan      html  css  js  c++  java
  • 多线程编程_CountDownLatch同步倒数计数器

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





     
  • 相关阅读:
    STM32 F4 DAC DMA Waveform Generator
    STM32 F4 General-purpose Timers for Periodic Interrupts
    Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式
    Python第十三天 django 1.6 导入模板 定义数据模型 访问数据库 GET和POST方法 SimpleCMDB项目 urllib模块 urllib2模块 httplib模块 django和web服务器整合 wsgi模块 gunicorn模块
    查看SQL Server服务运行帐户和SQL Server的所有注册表项
    Pycharm使用技巧(转载)
    SQL Server 2014内存优化表的使用场景
    Python第十天 print >> f,和fd.write()的区别 stdout的buffer 标准输入 标准输出 从控制台重定向到文件 标准错误 重定向 输出流和输入流 捕获sys.exit()调用 optparse argparse
    Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数
    Python第六天 类型转换
  • 原文地址:https://www.cnblogs.com/mingfeng002/p/6770119.html
Copyright © 2011-2022 走看看