栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java并发工具包之CountDownLatch

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java并发工具包之CountDownLatch

CountDownLatch 允 许 一个或多个 线 程等待其他 线 程完成操作。 假如有 这样 一个需求:我 们 需要解析一个 Excel 里多个 sheet 的数据,此 时 可以考 虑 使用多 线 程,每个 线 程解析一个 sheet 里的数据,等到所有的 sheet 都解析完之后,程序需要提示解析完 成。在 这 个需求中,要 实现 主 线 程等待所有 线 程完成 sheet 的解析操作。--摘自Java并发编程的艺术 针对上述的需求有2个解决方案,方案1就是使用jion(),方案2就是使用CountDownLatch; 首先介绍方案1的实现:
**
 * @PackageName:com.netty.obj.demo5 Description
 *  JOIN
 * @author:
 * @date:2022/1/12
 */
public class JoinCountDownLatchTest {
    public static void main(String[] args) throws InterruptedException {
        //1 创建一个线程解析sheet1
        Thread parser1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("sheet1 parser finish");
            }
        });
        //2 创建一个线程解析sheet2
        Thread parser2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("sheet2 parser finish");
            }
        });
        //3.启动线程1,2
        parser1.start();
        parser2.start();
        //4.调用线程的join方法,主线程main需要等待 线程 parser1,parser2执行完成后才往后执行主线程
        parser1.join();
        parser2.join();
        System.out.println("all parser finish");
    }
}

来看看join方法的源码:

public final void join() throws InterruptedException {
        join(0);
    }
public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

接下来看看方案2的实现方式:CountDownLatch

**
 * @PackageName:com.netty.obj.demo5.d1 Description
 * @author: 等待多线程完成的CountDownLatch
 * @date:2022/1/12
 */
public class CountDownLatchTest {
    static CountDownLatch c = new CountDownLatch(2);

    public static void main(String[] args) throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("parser1 finish");
                c.countDown();
                System.out.println("parser1 finish");
                c.countDown();
            }
        }).start();
        c.await();
        System.out.println("all parser finish");
    }
}
CountDownLatch 的构造函数接收一个 int 类 型的参数作 为计 数器,如果你想等待 N 个点完 成, 这 里就 传 入 N 。 当我 们调 用 CountDownLatch 的 countDown 方法 时 , N 就会减 1 , CountDownLatch 的 await 方法 会阻塞当前 线 程,直到 N 变 成零。由于 countDown 方法可以用在任何地方,所以 这 里 说 的 N 个 点,可以是 N 个 线 程,也可以是 1 个 线 程里的 N 个 执 行步 骤 。用在多个 线 程 时 ,只需要把 这 个 CountDownLatch 的引用 传递 到 线 程里即可。 如果有某个解析 sheet 的 线 程 处 理得比 较 慢,我 们 不可能 让 主 线 程一直等待,所以可以使 用另外一个 带 指定 时间 的 await 方法 ——await ( long time , TimeUnit unit ), 这 个方法等待特定 时 间 后,就会不再阻塞当前 线 程。 join 也有 类似的方法。--摘自Java并发编程的艺术 CountDownLatch 源码方法:
使当前线程等待,直到闩锁倒计时到零,除非线程是被中断interrupt
public void await() throws InterruptedException {
    sync.acquireSharedInterruptibly(1);
}
经过指定的等待时间使当前线程等待,直到闩锁倒计时到

零,除非线程是中断interrupt
public boolean await(long timeout, TimeUnit unit)
        throws InterruptedException {
        return sync.tryAcquireSharedNanos(1, unit.tonanos(timeout));
    }
递减闩锁计数,当计数为零时释放所有等待的线程
public void countDown() {
    sync.releaseShared(1);
}

返回当前计数

public long getCount() {
    return sync.getCount();
}
总结:本节内容案例主要来至《 Java并发编程的艺术》,通过学习作者的案例变通为自己的理解,可能在业务开发中会用到此工具
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/703967.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号