CyclicBarrier从小栗子来理解线程同步
我们生活中有这样一个情景,任务一是创建订单,任务二是派单,
当任务一,和任务二完成之后进行核对账款操作,
你可以抽象成任务一,和任务二完成之后通知任务三(核对账款)去完成。
如下图所示:
这里需要注意的是,因为两个线程分别执行任务一,任务二。我们必须抱着任务一,任务二同步。
假如一个快,一个慢的话分别进入队列那我们再去核账没有意义。因为这笔派单和能上一个订单。
贴上代码: import java.util.Vector; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; /** * 订单队列 */ static Vector<String> pv = new Vector<>(); /** * 派单队列 */ static Vector<String> dv= new Vector<>(); /** * 订单执行结果模拟 */ static AtomicInteger pvAi = new AtomicInteger(0); /** * 派单执行结果模拟 */ static AtomicInteger dvAi = new AtomicInteger(0); public static void main(String[] args) { Executor executor = Executors.newFixedThreadPool(1); CyclicBarrier cb = new CyclicBarrier(2,()->{ executor.execute(()->check()); });//计数器为2,每当计数器为0的时候触发依次check() Thread threadP = new Thread(()->{ while (true){ try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } pv.add(getPOrder()); try { cb.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); Thread threadD = new Thread(()->{ while (true){ try { TimeUnit.SECONDS.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); } dv.add(getDOrder()); try { cb.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); threadP.start(); threadD.start(); } static String getPOrder() { System.out.println("订单执行》》》"); return "POrder"+pvAi.incrementAndGet(); } static String getDOrder() { System.out.println("派单执行》》》"); return "DOrder"+dvAi.incrementAndGet(); } static String check() { String p= pv.remove(0); String d= dv.remove(0); checkAccount(p,d); return "checkOk"; } /** * 核对帐,需要订单结果和派单结果 * @return */ static void checkAccount(String p,String d) { System.out.println("核账执行》》》订单: "+p+" 派单: "+d); }
以下是打印结果: 一一对应
订单执行》》》
派单执行》》》
核账执行》》》订单: POrder1 派单: DOrder1
订单执行》》》
派单执行》》》
核账执行》》》订单: POrder2 派单: DOrder2
订单执行》》》
派单执行》》》
核账执行》》》订单: POrder3 派单: DOrder3