如图所示,这是需求,下面为代码实现
// 订单队列
Vector<P> pos;
// 派送单队列
Vector<D> dos;
// 执行回调的线程池
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();
}
CyclicBarrier的构造函数中能否不用线程池,之间调用回调函数?
可以,此时的回调函数会运行在最后await()线程之上,此时的问题就是下次的get()得等回调函数的执行完。
如果利用线程池则不需要等待回调函数执行完,实现了异步。
那么线程池的大小能否改为大于1的数?
不可以,只有单线程去取俩个队列中的数据才不会出错。
举个例子 第一个回调函数执行第一个队列的remove(0),第二个回调函数后来居上执行完第一个队列的remove(0),抢在了第一个回调函数前面执行 第二个队列的remove(0),那么此时俩个回调函数获取到的值并不是一一对应。
所以将线程池的大小设置为1,保证了回调函数执行的串行化。