import java.util.Queue; import java.util.Random; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * * 使用CountDownLatch来模拟马拉松比赛 * * @author 杨尚川 */ public class MarathonSimulator { public static void main(String[] args) throws Exception{ ExecutorService executorService = Executors.newCachedThreadPool(); int personCount = 3; final CountDownLatch prepare = new CountDownLatch(personCount); final CountDownLatch start = new CountDownLatch(1); final CountDownLatch end = new CountDownLatch(personCount); final Queue<String> queue = new ConcurrentLinkedQueue<>(); if(personCount < 3){ System.out.println("参赛人数必须 > 2"); return; } for(int i=1; i<=personCount; i++){ final int personNumber = i; executorService.submit(new Runnable() { @Override public void run() { //模拟准备时间,使用随机数 try{ Thread.sleep(new Random(personNumber).nextInt(1000)); }catch(Exception e){} System.out.println(personNumber+"号运动员准备完毕"); prepare.countDown(); try { //等待开始跑的命令 start.await(); }catch (Exception e){} System.out.println(personNumber+"号运动员开始跑"); long s = System.currentTimeMillis(); //模拟跑步时间,使用随机数 try{ Thread.sleep(new Random(personNumber).nextInt(10000)); }catch(Exception e){} long c = System.currentTimeMillis() - s; System.out.println(personNumber+"号运动员到达目的地,耗时:"+c+"毫秒"); end.countDown(); queue.add(personNumber+"号"); } }); } System.out.println("有"+personCount+"名运动员参加本次的马拉松比赛"); System.out.println("教练在等待运动员准备...\n"); prepare.await(); System.out.println("\n所有运动员准备完毕,教练开始喊:预备 --- 跑!"); start.countDown(); System.out.println("\n教练在等待所有的运动员跑完...\n"); end.await(); System.out.println("\n所有运动员都跑完了,开始颁奖啦:"); System.out.println("冠军是:"+queue.poll()); System.out.println("亚军是:"+queue.poll()); System.out.println("季军是:"+queue.poll()); executorService.shutdown(); } }
10人参加比赛程序运行之后的输出结果: 有10名运动员参加本次的马拉松比赛 教练在等待运动员准备... 2号运动员准备完毕 10号运动员准备完毕 7号运动员准备完毕 8号运动员准备完毕 5号运动员准备完毕 6号运动员准备完毕 3号运动员准备完毕 4号运动员准备完毕 1号运动员准备完毕 9号运动员准备完毕 所有运动员准备完毕,教练开始喊:预备 --- 跑! 教练在等待所有的运动员跑完... 2号运动员开始跑 7号运动员开始跑 3号运动员开始跑 4号运动员开始跑 9号运动员开始跑 10号运动员开始跑 1号运动员开始跑 6号运动员开始跑 5号运动员开始跑 8号运动员开始跑 4号运动员到达目的地,耗时:1866毫秒 8号运动员到达目的地,耗时:2367毫秒 3号运动员到达目的地,耗时:3736毫秒 7号运动员到达目的地,耗时:4241毫秒 2号运动员到达目的地,耗时:6113毫秒 6号运动员到达目的地,耗时:6616毫秒 10号运动员到达目的地,耗时:7117毫秒 1号运动员到达目的地,耗时:8989毫秒 5号运动员到达目的地,耗时:9491毫秒 9号运动员到达目的地,耗时:9993毫秒 所有运动员都跑完了,开始颁奖啦: 冠军是:4号 亚军是:8号 季军是:3号 3人参加比赛程序运行之后的输出结果: 有3名运动员参加本次的马拉松比赛 教练在等待运动员准备... 2号运动员准备完毕 3号运动员准备完毕 1号运动员准备完毕 所有运动员准备完毕,教练开始喊:预备 --- 跑! 教练在等待所有的运动员跑完... 2号运动员开始跑 1号运动员开始跑 3号运动员开始跑 3号运动员到达目的地,耗时:3737毫秒 2号运动员到达目的地,耗时:6112毫秒 1号运动员到达目的地,耗时:8990毫秒 所有运动员都跑完了,开始颁奖啦: 冠军是:3号 亚军是:2号 季军是:1号
相关推荐
递减锁存器CountDownLatch的使用以及注意事项!
java并发编程中CountDownLatch和CyclicBarrier的使用借鉴 java并发编程中CountDownLatch和CyclicBarrier是两个非常重要的线程控制和调度工具,经常被用于解决多线程程序设计中的线程等待问题。本文将对...
从上面的代码可以看出,作者使用 CountDownLatch 来同步多个线程的执行。首先,作者创建了一个 CountDownLatch 对象,并将其初始化为 1。然后,作者使用线程池来执行多个线程,每个线程都执行一个 Callable 任务。在...
2. **并发测试**:在测试中,可以创建多个线程模拟并发执行,然后使用 `CountDownLatch` 让测试代码等待所有并发操作完成,确保测试结果的正确性。 3. **框架设计**:在自定义框架或库中,如果有多个组件或服务需要...
Java 使用 CountDownLatch 等待多线程全部执行完成 CountDownLatch 是 Java 中的一个同步工具类,允许一个或多个线程等待其他线程完成操作。它的应用场景非常广泛,例如在处理大量数据时,可以使用多线程的方式处理...
这种情况下,我们可以使用CountDownLatch来实现线程的同步。 CountDownLatch的工作原理 CountDownLatch是JAVA提供的一种同步工具,主要用来让某个线程等待其他线程执行完毕后再继续执行。它的工作原理是:当我们...
CountDownLatch内部使用了AQS(AbstractQueuedSynchronizer)来实现同步控制。AQS维护了一个整型状态字段,对于CountDownLatch,这个状态就是计数器的值。`countDown()`方法相当于原子性地对状态进行减1操作,而`...
CountDownLatch是一个计数器,初始化时设定一个计数值,线程在执行任务之前会调用`countDown()`方法来减小计数值,直到计数值为0,所有等待的线程才会被释放并继续执行。这在多线程环境中常用来确保所有线程都完成...
2. **如何避免死锁与饥饿**:在使用CountDownLatch时,要确保所有线程都能正确调用`countDown()`,避免因某个线程异常而无法达到零导致死锁。 3. **如何选择合适的同步工具**:根据场景选择,如果需要所有线程执行完...
5. **一次性使用**:CountDownLatch的设计是一次性的,即一旦计数器归零,就不能再次使用。如果尝试再次调用`await()`或`countDown()`,它将抛出`IllegalStateException`。 6. **并发性能**:由于CountDownLatch是...
本文将详细介绍如何利用MyBatis结合多线程和CountDownLatch闭锁来实现数据的批量插入。 首先,我们来看`mybatis批处理`。MyBatis的批处理功能允许我们在一次数据库连接中执行多条SQL语句,从而减少了数据库连接的...
在上面的例子中,我们使用CountDownLatch来控制线程的执行顺序,使得主线程等待代表选手的线程执行完成后再执行。我们可以看到,通过CountDownLatch的使用,我们控制了线程的执行顺序。在上面的代码中,我们使用到...
例如,模拟一个团队赛跑场景,所有队员出发后,裁判(主线程)等待所有队员到达终点(调用`countDown()`),队员全部到达后,裁判宣布比赛结束(`await()`返回)。 5. **CountDownLatch的应用场景** - 多线程协同...
CountDownLatch 的工作机理是通过构造函数中的计数值来实现的,这个值只能被设置一次,而且 CountDownLatch 没有提供任何机制去重新设置这个计数值。主线程必须在启动其他线程后立即调用 CountDownLatch.await()方法...
- **并发任务分阶段执行**:一个大型任务可以被分解成多个子任务,使用 CountDownLatch 让所有子任务完成后,再执行下一步操作。 5. **注意事项**: - `CountDownLatch` 不是线程安全的,因此计数器一旦递减到零...
SpringBoot CountDownLatch 多任务并行处理的实现方法 本篇文章主要介绍了 SpringBoot 中使用 ...在我们的示例中,我们使用五个任务来模拟统计功能点的计算,但是使用 CountDownLatch 可以轻松地扩展到更多的任务。
在Main类中,创建了一个CountDownLatch对象`begSignal`用于等待所有运动员准备就绪,然后调用`countDown()`开始比赛;另一个CountDownLatch对象`endSignal`用于等待所有运动员到达终点,之后主线程可以继续发送比赛...
CountDownLatch 是 Java 中的一个同步工具类,位于 `java.util.concurrent` 包下,它主要用于多线程间的协作,...正确使用 CountDownLatch 可以提高程序的并发性能,避免不必要的等待,同时确保任务的正确顺序执行。
使用 CountDownLatch 需要创建一个实例并传入一个初始计数值,这个计数值表示需要等待的线程数量。然后,每个需要等待的线程在完成任务后调用 `countDown()` 方法,将计数值减一。主线程或其他需要等待的线程调用 `...
CountDownLatch与thread.join()的区别