多线程购物

项目架构如图:
在这里插入图片描述
Main

import java.util.*;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {

   static AtomicInteger threadNum=new AtomicInteger(0);


    public static final Shop shop=new Shop();

    public static void main(String[] args) {
         addProduct(1,10);
        String tmp=  shop.toString();
        shopping(200);
        System.out.println("--------初始数据--------");
        System.out.println(tmp);
        System.out.println();

        System.out.println();
        System.out.println("----  现在商店总数据--------");
        System.out.println(shop.toString());
        System.out.println();
    }

    public static void shopping(int userCount) {
        User[] users=new User[userCount];
        CountDownLatch countDownLatch=new CountDownLatch(userCount);
        for(int i=0;i<userCount;i++){
            users[i]=new User(countDownLatch);
            new Thread(users[i]).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        HashMap<String , Integer> objectObjectHashMap = new HashMap<>();
       for(User user:users){

          Map<String, Integer> stringIntegerMap = user.bag;
          Set<Map.Entry<String, Integer>> entries = stringIntegerMap.entrySet();
          for(Map.Entry<String, Integer> entry:entries){
              String key = entry.getKey();
              Integer orDefault = objectObjectHashMap.getOrDefault(key, 0);
              int num=orDefault+entry.getValue();
              objectObjectHashMap.put(key,num);
          }
      }
        System.out.println("-------用户拥有总数据--------");
        Set<Map.Entry<String, Integer>> entries = objectObjectHashMap.entrySet();
        for(Map.Entry<String, Integer> entry:entries){
            System.out.println("name:"+entry.getKey()+";value:"+entry.getValue());
        }

    }



    private static void addProduct(int threadSize,int preSize){

        Thread[] threads= new Thread[threadSize];
        CyclicBarrier cyclicBarrier = new CyclicBarrier(threadSize);//同时启动
        CountDownLatch countDownLatch=new CountDownLatch(threadSize);
        for(Thread thread:threads){
            thread=new Thread(new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        cyclicBarrier.await();
                    } catch( Exception e) {
                        return;
                    }
                    for(int i =0;i<preSize;i++){
                        int size=new Random().nextInt(10000)+10000;
                        int value=new Random().nextInt(10)+1;
                        shop.addProduct("product-"+i,size,value,"product memo");
                    }
                    countDownLatch.countDown();
                }
            }));
            thread.setName("thread"+threadNum.incrementAndGet());
            thread.start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Product

import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

public class Product {
    Integer id;
    String name;
    Integer value;
    AtomicInteger num;

    String memo;

    Object lock=new Object();

    public boolean buy(int count){
        if(num.get()>=count){
            synchronized (lock){
               if(num.get()>=count){
                  num.addAndGet(-count);
                  return true;
               }else {
                   return false;
               }
            }
        }
        return false;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

    public AtomicInteger getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = new AtomicInteger(num);
    }

    public void addNum(int num){
        this.num.addAndGet(num);
    }

    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }

    public int addNum(Integer num){
      return this.num.addAndGet(num);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Product product = (Product) o;
        return ((Product) o).getId()==this.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    @Override
    public String toString() {
        return "Product{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", value=" + value +
                ", num=" + num +
                '}'+'\n';
    }
}

Shop

import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class Shop {



    ConcurrentHashMap<String, Product> concurrentHashMapByString;
    AtomicInteger ShopSize;

    AtomicInteger shopId;

    public Shop() {
        this.shopId = new AtomicInteger(1);
        this.ShopSize = new AtomicInteger(0);
        this.concurrentHashMapByString = new ConcurrentHashMap<>();
    }

    public void addProduct(String name, Integer size, int value, String memo) {
        if (!concurrentHashMapByString.containsKey(name)) {
            //为空则放置一个新的对象
            Product product = new Product();
            product.setId(getShopId());
            product.setName(name);
            product.setNum(size);
            product.setValue(value);
            product.setMemo(memo);
            if (concurrentHashMapByString.putIfAbsent(name, product) == null) {
                ShopSize.incrementAndGet();
                System.out.println("product:" + name + " add successful num=" + size);
                return;
            }
            //置换不成功 继续
        }
        //存在数据,则将数据的num修改,map种的商品永远存在
        Product product = concurrentHashMapByString.get(name);
        product.addNum(value);
        System.out.println("product:" + name + " add successful num=" + size);
    }

    public int getShopId() {
        return this.shopId.getAndIncrement();
    }


    public boolean shopping(String name, User user, int count) throws ShopException {
        Product product = this.concurrentHashMapByString.get(name);
        if (product == null) {
            throw new ShopException(ShopException.productLess,"product cout  isnt enough , count:"+user.toString() );
        }
        //检查用户钱是否够
        int countMoney = product.getValue() * count;
        if (user.money.get() < countMoney) {
            throw new ShopException(ShopException.moneyLess,"user dont have money:"+user.toString() );
        }
        //开始购买
        user.lock.lock();
        boolean buy = product.buy(count);
        if (buy) {
            int i = user.delMoney(countMoney);
            //钱不足
            if (i == -1) {
                product.addNum(count);
                user.lock.unlock();
                throw new ShopException(ShopException.moneyLess,"money isnt enough money:"+user.toString()+",need: "+countMoney);
            }
            user.lock.unlock();
            return true;
        }else {
            //物品不足
            user.lock.unlock();
            throw new ShopException(ShopException.productLess,"product cout isnt enough,  count:"+product.num.get());
        }
    }

    @Override
    public String toString() {
        return "Shop{" +
                ", concurrentHashMapByString=" + Arrays.toString(concurrentHashMapByString.values().toArray()) +
                ", ShopSize=" + ShopSize +
                ", shopId=" + shopId +
                '}';
    }
}


ShopException

public class ShopException  extends   Exception{

    public static final int moneyLess=2;
    public static final int productLess=1;

    String message;

    int code ;

    public int getCode() {
        return code;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public ShopException(int code ,String msg){
        this.code=code;
            this.message=msg;
    }

}

User

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

public class User  implements Runnable{

    public static AtomicInteger idGenerator=new AtomicInteger(0);

    Integer id=idGenerator.incrementAndGet();

    AtomicInteger money=new AtomicInteger(5000);

    ReentrantLock lock=new ReentrantLock();


    Map<String,Integer> bag=new HashMap<>();

    CountDownLatch countDownLatch;
    public User(CountDownLatch countDownLatch) {
        this.countDownLatch=countDownLatch;

    }

    @Override
    public String toString() {
        return "User-"+id+"{" +
                "money=" + money.get() +
                '}';
    }

    public int delMoney(int count){
        if(money.get()<count){
            return -1;
        }
        lock.lock();
        int i = money.addAndGet(-count);
        lock.unlock();
        return i;
    }

    @Override
    public void run() {


        for(int i=0;i<5000;i++){
            int id = new Random().nextInt(Main.shop.ShopSize.get());
            boolean shopping = false;
            String name = "product-" + id;
            int count = new Random().nextInt(5);
            try {
                shopping = Main.shop.shopping(name, this,count);
                if(shopping){
                    Integer integer = bag.getOrDefault(name,0);
                    count=count+integer;
                    bag.put(name,count);
                }else {
                    System.out.println(i+"--shopping error: "+name+";product:"+Main.shop.concurrentHashMapByString.get(name).toString());
                }
            } catch (ShopException e) {
                System.err.println(e.getMessage());
                if (e.getCode()==ShopException.moneyLess){
                    countDownLatch.countDown();
                    return;
                }
            }

        }
        countDownLatch.countDown();
    }
}

.iml

<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
  <component name="NewModuleRootManager" inherit-compiler-output="true">
    <exclude-output />
    <content url="file://$MODULE_DIR$">
      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
  </component>
</module>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值