java多线程(六) 之 店铺买卖多线程练习题

一. 店铺买卖题目如下:

商家: 可以采购商品上架到店铺,并支付成本费用
买家: 可以在店铺购买上架的商品,并把钱支付给店铺

假设有n种商品可供商家上架:
售价由商家可以自定
假设初始数据如下:
商品名称    成本  售价
充气娃娃    98  388
避孕套 8   19
性感蕾丝    99  298
避孕药 48  78
...

目的: 
记录一天(假设为1000ms)内的所有交易记录,最后统计出店铺当天的收益
需要注意的是,一个店铺,可以由多个商家管理,他们都可以上架商品到店铺.

二. 解题思路:
这里写图片描述
核心的类就是店铺类了:
由图可见,该类需要对外提供至少四个public方法:
1) 提供给店铺商家进购商品方法
2) 提供给店铺商家修改商品价格的方法
3) 提供给客户购买商品的方法
4) 商品展示

还有一些题目需求方法:
1) 交易记录
2) 计算当天收益

需要保证线程安全的数据为:
1) 商品Goods的数量
2) 商品Goods的价格
3) 店铺的资金

三.数据模型结构
这里写图片描述

四. 程序源码
1.Goods类:

public class Goods {

    //售价
    private int price;
    //商品名称
    private final String name;
    //成本
    private final int cost;

    public Goods(String name, int cost) {
        super();
        this.name = name;
        this.cost = cost;
    }

    public Goods(String name, int cost,int price) {
        this(name,cost);
        this.price = price;
    }

    public synchronized int getPrice() {
        return price;
    }

    synchronized void setPrice(int price){
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public int getCost() {
        return cost;
    }

    @Override
    public String toString() {
        return name+"+"+cost+"+"+price;
    }
}

2.Shop类

import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 商铺
 */
public class Shop {
    //商家资金
    private volatile Integer money;

    //该店铺可以进购的所有商品
    protected final Goods []all;

    private final Map<Goods,Integer> goodss;
    private final Map<Goods,Integer> showGoodss;

    protected Shop(int money,Goods all[]) {
        goodss = new ConcurrentHashMap<>();
        showGoodss = Collections.unmodifiableMap(goodss);
        this.all = all;
        this.money = money;
    }

    protected Map<Goods,Integer> getGoodss(){
        return showGoodss;
    }

    protected boolean setPrice(Goods goods, int price){
        if(goodss.containsKey(goods)){
            goods.setPrice(price);
            return true;
        }
        return false;
    }

    protected boolean addGoods(Goods goods,int quantity){
        int cost = goods.getCost() * quantity;
        return cost(goods, quantity, cost);
    }

    protected boolean buyGoods(Goods goods,int quantity){
        synchronized (goods) {
            if(goodss.get(goods)>=quantity){
                int cost = goods.getPrice()*-quantity;
                cost(goods,-quantity,cost);
                return true;
            }
        }
        return false;
    }

    private synchronized boolean cost(Goods goods,int quantity,int cost){
        if(cost<=this.money){
            this.money = this.money - cost;
            goodss.compute(goods, (k,v)->v==null?quantity:v+quantity);
            if(goodss.get(goods)==0)
                goodss.remove(goods);
            return true;
        }
        return false;
    }

    protected int getMoney(){
        return money;
    }

}

3.InfoShop类

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class InfoShop extends Shop{

    private static final String TRUE = "成功";
    private static final String FALSE = "失败";

    private StringBuffer info = new StringBuffer();
    private final int startMoney;

    public InfoShop(int money,Goods []all) {
        super(money,all);
        startMoney = money;
    }

    public boolean addGoods(String people,Goods goods, int quantity) {
        boolean flag =  super.addGoods(goods, quantity);
        info.append(people+"\t添加"+goods.getName()+"\t数量为"+quantity+"\t"+(flag?TRUE:FALSE)+"\n");
        return flag;
    }

    public boolean buyGoods(String people,Goods goods, int quantity) {
        boolean flag = super.buyGoods(goods, quantity);
        info.append(people+"购买"+goods.getName()+"\t数量为"+quantity+"\t"+(flag?TRUE:FALSE)+"\n");
        return flag;
    }

    public boolean setPrice(String people,Goods goods,int price){
        boolean flag = super.setPrice(goods, price);
        info.append(people+"设置"+goods.getName()+"\t的价格为"+price+"\t"+(flag?TRUE:FALSE)+"\n");
        return flag;
    }

    public Map<Goods, Integer> inShop(String people) {
        info.append(people+"进入店铺"+"\n");
        return super.getGoodss();
    }

    public void OutShop(String people){
        info.append(people+"离开店铺"+"\n");
    }

    public List<Goods> getAll(){
        return Collections.unmodifiableList(Arrays.asList(all));
    }

    @Override
    public String toString() {
        return info.toString();
    }

    public int getProfit() {
        return super.getMoney()-startMoney;
    }
}

4.模拟商家Seller类

public class Seller implements Runnable{

    private final InfoShop shop;
    private final String name;

    public Seller(InfoShop shop,String name) {
        this.shop = shop;
        this.name = name;
    }
    @Override
    public void run() {
        long start = System.currentTimeMillis();
        while(System.currentTimeMillis()-start<1000){
            int index = (int) (Math.random()*shop.getAll().size());
            Goods goods = shop.getAll().get(index);
            if(Math.random()>Math.random()-0.1){
                shop.addGoods(name, goods, (int) (Math.random()*10));
            }else{
                shop.setPrice(name, goods, (int) (Math.random()*goods.getCost()/5.0));
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

5.模拟客户Buyer类

import java.util.Map;

public class Buyer implements Runnable{

    private final String name;
    private final InfoShop shop;

    public Buyer(InfoShop shop, String name) {
        this.name = name;
        this.shop = shop;
    }

    @Override
    public void run() {
        int index = (int) (Math.random()*shop.getAll().size());
        Goods goods = shop.getAll().get(index);
        int quantity = (int) (Math.random()*6);
        Map<Goods,Integer> map = shop.inShop(name);
        if(map.containsKey(goods)){
            if(quantity>map.get(goods)){
                quantity = map.get(goods);
            }
            shop.buyGoods(name, goods, quantity);
        }
        shop.OutShop(name);
    }

}

7.测试类Main

public class Main {
    public static void main(String[] args) {
        final Goods []goods = {
            new Goods("充气娃娃",98,388),
            new Goods("避孕套",8,19),
            new Goods("性感蕾丝",99,298),
            new Goods("避孕药",48,78)
        };
        InfoShop shop = new InfoShop(9999,goods);
        Seller s1 = new Seller(shop,"张三");
        Seller s2 = new Seller(shop,"李四");
        Seller s3 = new Seller(shop,"王五");
        new Thread(s1).start();
        new Thread(s2).start();
        new Thread(s3).start();

        try {
            Thread.sleep(500);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        for(char a='a';a<='z';a++){
            new Thread(new Buyer(shop,a+"")).start();
        }

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("今日店铺现场记录:\n"+shop.toString());
        System.out.println(shop.inShop("master"));
        System.out.println("店铺剩余资金:\n"+shop.getProfit());
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值