爱情也可以买卖么, 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=小张洗衣液)])

在这里插入图片描述
在这里插入图片描述

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