愛情也可以買賣麼, Semaphore Pattern(信號量模式) 來擺攤

目的

保護一組資源中的每個資源都不會受到併發訪問而導致不一致

例子代碼

男: 砸了你的攤, 逼着你離開, 最後知道真相的我眼淚掉下來, 砸了你的攤, 我背了良心債, 就算付出再多感情也再買不回來

在這裏插入圖片描述
在這裏插入圖片描述

女: 當初是你要分開, 分開就分開, 如今又要用真(政)愛(策), 把我哄回來, 擺攤不是你想擺, 想擺就能擺, 讓我掙開, 讓我明白, 放手你的愛

擺攤經濟一出, 各國人都開啓了擺攤之旅:

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

可是攤位有限, 不能隨便擺哦, 我們來講講這裏面的故事:

我們定義一下貨物類:

//商品
@Data
@AllArgsConstructor
public class Goods {
    private String name;
}

定義一個攤位類:

//攤位
@Data
@AllArgsConstructor
public class Stall {
    private Integer number;
    private String name;
    private List<Goods> saleGoods;
}

定義一個擺攤的人:

//擺攤人
@Data
@AllArgsConstructor
public class People {
    private String name;
    private List<Goods> saleGoods;
}

我們三個人同時去擺攤:

List<People> peopleList = new ArrayList<>();
peopleList.add(new People("小李", Arrays.asList(new Goods("小李皮鞋"), new Goods("小李運動鞋"))));
peopleList.add(new People("小王", Arrays.asList(new Goods("小王西瓜"), new Goods("小王椰子"))));
peopleList.add(new People("小張", Arrays.asList(new Goods("小張肥皂"), new Goods("小張洗衣液"))));
List<Stall> stallList = new ArrayList<>();
stallList.add(new Stall(1,"攤位一",new ArrayList<>()));
stallList.add(new Stall(2,"攤位二",new ArrayList<>()));
peopleList.parallelStream().forEach(
        (people) -> {
            for (Stall stall : stallList) {
                if(stall.getSaleGoods().isEmpty()) {
                    stall.setName(people.getName() + "的攤位");
                    //拜訪貨物中
                    putGoods2Stall();
                    stall.setSaleGoods(people.getSaleGoods());
                }
            }
        }
);
System.out.println(stallList.toString());

輸出:

[Stall(number=1, name=小李的攤位, saleGoods=[Goods(name=小李皮鞋), Goods(name=小李運動鞋)]), Stall(number=2, name=小王的攤位, saleGoods=[Goods(name=小張肥皂), Goods(name=小張洗衣液)])]

問題分析

這個和互斥模式是一樣的, 主要是狀態的不一致, 小王賣了小張的貨, 如果用互斥模式來解決也沒什麼問題, 就是如果對stallList 加鎖粒度太大, 併發不高, 如果是對單個攤位加鎖, 要注意加鎖順序, 代碼也會複雜一些.

信號量模式

List<People> peopleList = new ArrayList<>();
peopleList.add(new People("小李", Arrays.asList(new Goods("小李皮鞋"), new Goods("小李運動鞋"))));
peopleList.add(new People("小王", Arrays.asList(new Goods("小王西瓜"), new Goods("小王椰子"))));
peopleList.add(new People("小張", Arrays.asList(new Goods("小張肥皂"), new Goods("小張洗衣液"))));

Semaphore semaphore = new Semaphore(2);

peopleList.parallelStream().forEach(
        (people) -> {
            try {
                semaphore.acquire();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println(people.getName() + "開始擺攤");
            Stall stall = new Stall();
            stall.setName(people.getName() + "的攤位");
            //擺放貨物中
            putGoods2Stall();
            stall.setSaleGoods(people.getSaleGoods());
            System.out.println(LocalDateTime.now() + "" + stall.toString());
            semaphore.release();
        }
);

輸出:

小王開始擺攤
小李開始擺攤
2020-06-06T13:04:03.710Stall(number=null, name=小王的攤位, saleGoods=[Goods(name=小王西瓜), Goods(name=小王椰子)])
2020-06-06T13:04:03.710Stall(number=null, name=小李的攤位, saleGoods=[Goods(name=小李皮鞋), Goods(name=小李運動鞋)])
小張開始擺攤
2020-06-06T13:04:05.713Stall(number=null, name=小張的攤位, saleGoods=[Goods(name=小張肥皂), Goods(name=小張洗衣液)])

在這裏插入圖片描述
在這裏插入圖片描述

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