爪哇中的CountDownLatch

CountDownLatch
is synchronisation aid that allow one or more 线s to wait until set of operations being performed in other 线s completes.闩锁.countDown()
once they complete some operation.So count is reduced by 1 whenever 闩锁.countDown()
method get called, so if count is n 这意味着计数可以用作 n 线程必须完成某些操作或必须完成某些操作 n 次。
例如:
下图将使您清楚。它是一个 例 如何使用CountDownLatch。
程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
包 组织.Arpit.爪哇2blog.线; 进口 爪哇.实用程序.同时.CountDownLatch; 上市 类 用户界面 初始化 实施 可运行{ CountDownLatch 闩锁; 用户界面 初始化(CountDownLatch 闩锁) { 这个.闩锁=闩锁; } @覆写 上市 虚空 跑() { 系统.出.打印(“初始化UI”); 尝试 { 线.睡觉(3000); } 抓住 (InterruptedException e) { // TODO自动生成的catch块 e.printStackTrace(); } 系统.出.打印(“完成UI初始化”); 闩锁.倒数(); } } |
创建一个名为记录初始化.java的类。完成后,该线程将执行latch.countDown()。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
包 组织.Arpit.爪哇2blog.线; 进口 爪哇.实用程序.同时.CountDownLatch; 上市 类 记录初始化 实施 可运行{ CountDownLatch 闩锁; 记录初始化(CountDownLatch 闩锁) { 这个.闩锁=闩锁; } @覆写 上市 虚空 跑() { 系统.出.打印(“初始化日志记录”); 尝试 { 线.睡觉(2000); } 抓住 (InterruptedException e) { // TODO自动生成的catch块 e.printStackTrace(); } 系统.出.打印(“完成日志记录初始化”); 闩锁.倒数(); } } |
创建一个名为数据库初始化.java的类。完成后,该线程将执行latch.countDown()。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
包 组织.Arpit.爪哇2blog.线; 进口 爪哇.实用程序.同时.CountDownLatch; 上市 类 数据库初始化 实施 可运行{ CountDownLatch 闩锁; 数据库初始化(CountDownLatch 闩锁) { 这个.闩锁=闩锁; } @覆写 上市 虚空 跑() { 系统.出.打印(“初始化数据库”); 尝试 { 线.睡觉(5000); } 抓住 (InterruptedException e) { // TODO自动生成的catch块 e.printStackTrace(); } 系统.出.打印(“完成数据库初始化”); 闩锁.倒数(); } } |
创建一个CountDownLatchMain.java类。这将是主线程,它将等待UIInitialization,数据库初始化和记录初始化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
包 组织.Arpit.爪哇2blog.线; 进口 爪哇.实用程序.同时.CountDownLatch; 上市 类 CountDownLatchMain { 上市 静态的 虚空 主要(串[] args) { 尝试 { CountDownLatch 闩锁 = 新 CountDownLatch(3); //初始化三个相关线程,即UI,数据库和日志记录 用户界面 初始化 ui初始化 = 新 用户界面 初始化(闩锁); 线 uiThread = 新 线(ui初始化); 数据库初始化 数据库初始化 = 新 数据库初始化(闩锁); 线 数据库Thread = 新 线(数据库初始化); 记录初始化 loggingInitialization = 新 记录初始化(闩锁); 线 loggingThread = 新 线(loggingInitialization); uiThread.开始(); 数据库Thread.开始(); loggingThread.开始(); //主线程将等待直到以上线程完成 闩锁.等待(); 系统.出.打印(“初始化已完成,主线程可以立即进行”); } 抓住 (InterruptedException e) { e.printStackTrace(); } } } |
当您运行上述程序时,将得到以下输出:
1 2 3 4 5 6 7 8 9 |
初始化中 用户界面 初始化中 数据库 初始化中 记录中 完成了 与 记录中 初始化 完成了 与 用户界面 初始化 完成了 与 数据库 初始化 初始化 拥有 是 已完成, 主要 线 能够 继续 现在 |
为什么不使用join而不是CountDownLatch:
如您所知,您也可以在这种情况下使用连接,但是您必须手动处理它。大多数人现在使用ExecutorService处理线程,而CountDownLatch可以很好地使用它。由于CountDownLatch是面向任务的,因此您可以将多个任务提交到线程池,并且一旦其他依赖线程集完成,CountDownLatch将确保执行原始线程。
请通过 前50个Java核心面试问题 了解更多面试问题。