《Java并发编程实战》课程笔记(十二)
CountDownLatch 和 CyclicBarrier:如何让多线程步调一致?
原始对账系统
利用并行优化对账系统
- 对于串行化的系统,优化性能首先想到的是能否利用多线程并行处理。
用 CountDownLatch 实现线程等待
- while 循环里面每次都会创建新的线程,而创建线程可是个耗时的操作。所以最好是创建出来的线程能够循环利用,线程池就能解决这个问题。
Executor executor = Executors.newFixedThreadPool(2);
while (存在未对账订单) {
CountDownLatch latch = new CountDownLatch(2);
executor.execute(() -> {
pos = getPOrders();
latch.countDown();
});
executor.execute(()-> {
dos = getDOrders();
latch.countDown();
});
latch.await();
diff = check(pos, dos);
save(diff);
}
- 我们将 getPOrders() 和 getDOrders() 这两个查询操作并行了,但这两个查询操作和对账操作 check()、save() 之间还是串行的。很显然,这两个查询操作和对账操作也是可以并行的,也就是说,在执行对账操作的时候,可以同时去执行下一轮的查询操作。
- 针对对账这个项目,我设计了两个队列,并且两个队列的元素之间还有对应关系。
- 订单查询操作将订单查询结果插入订单队列,派送单查询操作将派送单插入派送单队列,这两个队列的元素之间是有对应关系的。
- 两个队列的好处是,对账操作可以每次从订单队列出一个元素,从派送单队列出一个元素,然后对这两个元素执行对账操作,这样数据一定不会乱掉。
- ⼀个线程 T1 执行订单的查询工作,一个线程 T2 执行派送单的查询工作,当线程 T1 和 T2 都各自生产完 1 条数据的时候,通知线程 T3 执行对账操作。
- 线程 T1 和线程 T2 只有都生产完 1 条数据的时候,才能一起向下执行,也就是说,线程 T1 和线程 T2 要互相等待,步调要一致。
- 同时当线程 T1和 T2 都生产完一条数据的时候,还要能够通知线程 T3 执行对账操作。
用 CyclicBarrier 实现线程同步
- 我们首先创建了一个计数器初始值为 2 的 CyclicBarrier,你需要注意的是创建 CyclicBarrier 的时候,我们还传入了一个回调函数,当计数器减到 0 的时候,会调用这个回调函数。
- 线程 T1 负责查询订单,当查出一条时,调用 barrier.await() 来将计数器减 1,同时等待计数器变成 0;
- 线程 T2 负责查询派送单,当查出一条时,也调用 barrier.await() 来将计数器减 1,同时等待计数器变成 0;
- 当 T1 和 T2 都调用 barrier.await() 的时候,计数器会减到 0,此时 T1 和 T2 就可以执行下⼀条语句了,同时会调用 barrier 的回调函数来执行对账操作。
- CyclicBarrier 的计数器有自动重置的功能,当减到 0 的时候,会自动重置你设置的初始值。
Vector<P> pos;
Vector<D> pos;
Executor executor = Executors.newFixedThreadPool(1);
final CyclicBarrier barrier = new CyclicBarrier(2, () -> { executor.execute(() -> check()); });
void check() {
P p = pos.remove(0);
D d = dos.remove(0);
diff = check(p, d);
save(diff);
}
void checkAll() {
Thread t1 = new Thread(() -> {
while (存在未对账订单) {
pos.add(getPOrders());
barrier.await();
}
});
t1.start();
Thread T2 = new Thread(()->{
while(存在未对账订单){
dos.add(getDOrders());
barrier.await();
}
});
T2.start();
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/612613.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!