zoukankan      html  css  js  c++  java
  • thread_CountDownLatch同步计数器

    CountDownLatch类是一个同步计数器,构造时传入int参数,该参数就是计数器的初始值,每调用一次countDown()方法,计数器减1,
    计数器大于0 时,await()方法会阻塞程序继续执行
     CountDownLatch如其所写,是一个倒计数的锁存器,当计数减至0时触发特定的事件。利用这种特性,可以让主线程等待子线程的结束。
    1.一个模拟运动员比赛的例子 

    class Player implements Runnable {
        private int id;
        private CountDownLatch begin;
        private CountDownLatch end;
    
        public Player(int i, CountDownLatch begin, CountDownLatch end) {
            super();
            this.id = i;
            this.begin = begin;
            this.end = end;
        }
    
        @Override
        public void run() {
            try {
                begin.await();                                 // 等待begin的状态为0
                Thread.sleep((long) (Math.random() * 100));    // 随机分配时间,即运动员完成时间
                System.out.println("Play" + id + " arrived.");
                
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                end.countDown();                              // 使end状态减1,最终减至0
            }
        }
    }
    public class CountDownLatchTest {
        private static final int PLAYER_AMOUNT = 5;
    
        @Test
        public void RaceTest1( ) {
            // 对于每位运动员,CountDownLatch减1后即结束比赛
            CountDownLatch begin = new CountDownLatch(1);
            
            // 对于整个比赛,所有运动员结束后才算结束
            CountDownLatch end = new CountDownLatch(PLAYER_AMOUNT);
            Player[] plays = new Player[PLAYER_AMOUNT];
    
            for (int i = 0; i < PLAYER_AMOUNT; i++)
                plays[i] = new Player(i + 1, begin, end);
    
            // 设置特定的线程池,大小为5
            ExecutorService exe = Executors.newFixedThreadPool(PLAYER_AMOUNT);
            for (Player p : plays){
                exe.execute(p);                     // 分配线程            
            }
    
            System.out.println("Race begins!");
            begin.countDown();
            
            try {
                end.await();                        // 等待end状态变为0,即为比赛结束
                
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                System.out.println("Race ends!");
            }
            exe.shutdown();
        }
    }

    2.健康检查

    public class CheckHealthStartup {
        // List of service checkers
        private static List<BaseHealthChecker> _services;
    
        // This latch will be used to wait on
        private static CountDownLatch _latch;
    
        private CheckHealthStartup() {
        }
    
        private final static CheckHealthStartup INSTANCE = new CheckHealthStartup();
    
        public static CheckHealthStartup getInstance() {
            return INSTANCE;
        }
    
        public static boolean checkExternalServices() throws Exception {
            // Initialize the latch with number of service checkers
            _latch = new CountDownLatch(2);
            _services = new ArrayList<BaseHealthChecker>();
            // All add checker in lists
    
            _services.add(new NetworkHealthChecker(_latch));
            _services.add(new DatabaseHealthChecker(_latch));
    
            // Start service checkers using executor framework
            Executor executor = Executors.newFixedThreadPool(_services.size());
    
            for (final BaseHealthChecker v : _services) {
                executor.execute(v);
            }
    
            // Now wait till all services are checked
            _latch.await();
    
            // Services are file and now proceed startup
            for (final BaseHealthChecker v : _services) {
                if (!v.isServiceUp()) {
                    return false;
                }
            }
            return true;
        }
    
        public static void main(String[] args) {
            boolean result = false;
            try {
                result = CheckHealthStartup.checkExternalServices();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("External services validation completed !! Result was :: " + result);
            
        }
    }
    
    class NetworkHealthChecker extends BaseHealthChecker {
        public NetworkHealthChecker(CountDownLatch latch) {
            super("Network Service", latch);
        }
    
        @Override
        public void verifyService() {
            System.out.println("Checking " + this.getServiceName());
            try {
                Thread.sleep(7000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(this.getServiceName() + " is UP");
        }
    }
    
    class DatabaseHealthChecker extends BaseHealthChecker {
        public DatabaseHealthChecker(CountDownLatch latch) {
            super("Database Service", latch);
        }
    
        @Override
        public void verifyService() {
            System.out.println("Checking " + this.getServiceName());
            try {
                Thread.sleep(7000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(this.getServiceName() + " is UP");
        }
    }
    
    abstract class BaseHealthChecker implements Runnable {
    
        private CountDownLatch _latch;
        private String _serviceName;
        private boolean _serviceUp;
    
        // Get latch object in constructor so that after completing the task, thread
        // can countDown() the latch
        public BaseHealthChecker(String serviceName, CountDownLatch latch) {
            super();
            this._latch = latch;
            this._serviceName = serviceName;
            this._serviceUp = false;
        }
    
        @Override
        public void run() {
            try {
                verifyService();
                _serviceUp = true;
            } catch (Throwable t) {
                t.printStackTrace(System.err);
                _serviceUp = false;
            } finally {
                if (_latch != null) {
                    _latch.countDown();
                }
            }
        }
    
        public String getServiceName() {
            return _serviceName;
        }
    
        public boolean isServiceUp() {
            return _serviceUp;
        }
    
        // This methos needs to be implemented by all specific service checker
        public abstract void verifyService();
    }
  • 相关阅读:
    java.lang.OutOfMemoryError: Java heap space解决办法
    android网络图片加载缓存,避免重复加载。
    Android控制软键盘拉起
    mysql create database 指定utf-8编码
    仿黑客帝国文字雨效果
    C++循环去掉文件的后缀名
    使用python读取多重文件夹下的word(doc、docx)文件,并处理存储到excel(xls、xlsx)文件
    Python操作文件夹
    (转载)Python:列表作为参数
    595. Big Countries (Easy)
  • 原文地址:https://www.cnblogs.com/dengzy/p/5800606.html
Copyright © 2011-2022 走看看