Java线程之闭锁

 闭锁是一种同步工具类,可以延迟线程的进度直到其到达终止状态。闭锁的作用相当于一扇门:在闭锁到达结束状态之前,这扇门一直是关闭的,并且没有任何线程能通过,当到达结束状态时,这扇门会打开并允许所有的线程通过。当闭锁到达结束状态后,将不会再改变状态,因此这扇门将永远保持打开状态。闭锁可以用来确保某些活动直到其他活动都完成后才继续执行,例如:

  • 确保某个计算再其需要的所有资源都被初始化之后才继续执行。二元闭锁(包括两个状态)可以用来表示“资源R已经被初始化”,而所有需要R的操作都必须先在这个闭锁上等待。
  • 确保某个服务在其依赖的所有其他服务都已经启动之后才启动。每个服务都有一个相关的二元闭锁。每当启动服务S时,将首先在S依赖的其他服务的闭锁上等待,在所有依赖的服务都启动后会释放闭锁S,这样其他依赖S的服务才能继续执行。
  • 等待直到某个操作的所有参与者(例如,在多玩家游戏中的所有玩家)都就绪时,闭锁将到达结束状态。

CountDownLatch是一种灵活的闭锁实现,可以在上述情况中使用,它可以使一个或多个线程等待一组事件发生。闭锁状包括一个计数器,该计数器被初始化为一个正数,表示需要等待的事件数量。countDown方法递减计数器,表示有一个事件已经发生了,而await方法等待计数器达到零,这表示所有需要等待的事件都已经发生。如果计数器的值为非零,那么await会在一直阻塞直到计数器为零。或者等待中的线程中断,或者等待超时。

public static long timeTTasks(int nThreads, final Runnable task) throws InterruptedException {
        final CountDownLatch startGate = new CountDownLatch(1);//传入计数器的大小
        final CountDownLatch endGate = new CountDownLatch(nThreads);
        for (int i = 0; i < nThreads; i++) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("name:"+Thread.currentThread().getName()+"开始等待");
                        startGate.await();//等待
                        System.out.println("name:"+Thread.currentThread().getName()+"开始执行");
                        try {
                            task.run();
                        } finally {
                            endGate.countDown();//计数器减一
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start();
        }
        long start = System.nanoTime();
        Thread.sleep(3000);
        System.out.println("释放startGate");
        startGate.countDown();//计数器减一
        endGate.await();//等待
        long end = System.nanoTime();
        return end - start;
    }

猜你喜欢

转载自blog.csdn.net/lmh_19941113/article/details/85048526