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
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章