一. 店铺买卖题目如下:
商家: 可以采购商品上架到店铺,并支付成本费用
买家: 可以在店铺购买上架的商品,并把钱支付给店铺
假设有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());
}
}