java编程思想笔记-并发之CountDownLatch

CountDownLatch使用简介

1.CountDownLatch用来同步一个或者多个任务,强制它们等待由其他任务执行的一组操作
2.CountDownLatch设定的初始值只能设置一次,不能重置,使用countDown()来减小这个值,如果希望这个值可以被重置可以使用CycliBarrier

CountDownLatch使用示例

在并发编程的时候通常有这样的需求,在main函数运行多个线程,在这些线程运行结束之前,main函数不能继续向下执行,如下便是一个统计发起的多个线程运行总时间的例子

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        final RpcProxy rpcProxy = context.getBean(RpcProxy.class);
        int threadNum = 10;
        int loopCount = 100;
        ExecutorService executorService = Executors.newFixedThreadPool(threadNum);
        //传入的loopCount是发起的线程总数
        final CountDownLatch latch = new CountDownLatch(loopCount);
        try {
            long start = System.currentTimeMillis();
            //利用循环发起多个线程
            for (int i = 0; i < loopCount; i++) {
                final int j = i;
                executorService.submit(new Runnable() {
                    @Override
                    public void run() {
                        HelloService helloService = rpcProxy.create(HelloService.class);
                        String result = helloService.hello("from client4-" + j);
                        System.out.println("from client4-" + j + ",result->" + result);
                        //每个线程运行完就通过CountDown减一
                        latch.countDown();
                    }
                });
            }
            //主线程在此阻塞,直到其它线程都运行结束
            latch.await();
            long time = System.currentTimeMillis() - start;
            System.out.println("thread: " + threadNum);
            System.out.println("loop: " + loopCount);
            System.out.println("time: " + time + "ms");
            System.out.println("tps: " + (double) loopCount / ((double) time / 1000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            executorService.shutdown();
        }
        System.exit(0);
    }

接下来这个是Zookeeper的例子
Zookeeper实例化的时候并没有真正的和ZooKeeper服务器建立连接,Zookeeper客户端和服务器会话的建立是异步的过程,如果我们需要Zookeeper实例与客户端真正建立连接后再进一步处理,我们可以采用如下的方法

public class ZKSession implements Watcher{
    private static CountDownLatch connectedSemaphore=new CountDownLatch(1);
    @Override
    public void process(WatchedEvent watchedEvent) {
        System.out.println("Receive watched event:"+watchedEvent);
        if (Event.KeeperState.SyncConnected==watchedEvent.getState()){
           //得到服务器连接完毕的通知后调用countdown
            connectedSemaphore.countDown();
        }
    }

    public static void main(String[] args) throws IOException {
        ZooKeeper zooKeeper=new ZooKeeper("192.168.101.129:2181",5000,new ZKSession());
        System.out.println(zooKeeper.getState());
        try {
        //主线程在Zookeeper实例与Zookeeper建立连接之前始终阻塞
            connectedSemaphore.await();
        } catch (InterruptedException e) {

        }
        System.out.println("ZooKeeper session established");
    }
}

你可能感兴趣的:(并发,java)