当前位置:网站首页>Multi thread shopping
Multi thread shopping
2022-07-29 07:33:00 【langxiong_ one thousand and nine】
Project architecture is shown in the figure :
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("-------- Initial data --------");
System.out.println(tmp);
System.out.println();
System.out.println();
System.out.println("---- Now the total data of the store --------");
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("------- Users have total data --------");
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);// At the same time to start
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)) {
// If it is empty, a new object will be placed
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;
}
// The replacement is unsuccessful continue
}
// There is data , Then... Of the data num modify ,map Products of all kinds will always exist
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() );
}
// Check whether the user has enough money
int countMoney = product.getValue() * count;
if (user.money.get() < countMoney) {
throw new ShopException(ShopException.moneyLess,"user dont have money:"+user.toString() );
}
// Start buying
user.lock.lock();
boolean buy = product.buy(count);
if (buy) {
int i = user.delMoney(countMoney);
// Insufficient money
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 {
// Insufficient items
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>
边栏推荐
猜你喜欢

How does MySQL convert rows to columns?

js第四天流程控制(if语句和switch语句)

MySQL uses the client and select methods to view the summary of blob type fields
Scala 高阶(十):Scala中的异常处理

【MYSQL】-【子查询】

I, 28, a tester, was ruthlessly dismissed in October: I want to remind people who are still learning to test

Using C language to skillfully realize the chess game -- Sanzi chess

leetcode力扣经典问题——4.寻找两个正序数组的中位数

Use custom annotations to verify the size of the list

新生代公链再攻「不可能三角」
随机推荐
js第四天流程控制(if语句和switch语句)
Starting process of raspberry pie
[summer daily question] Luogu p4414 [coci2006-2007 2] ABC
Leetcode 209. subarray with the smallest length (2022.07.28)
Introduction and introduction of logback
Sqlmap(SQL注入自动化工具)
CDC source can quit after reading MySQL snapshot split
3-全局异常处理
Can I specify memory parameters in SQL statements?
Meeting notice of OA project (Query & whether to attend the meeting & feedback details)
[summer daily question] Luogu p6461 [coci2006-2007 5] trik
PAT甲级 1150 旅行商问题
一篇长文---深入理解synchronized
UPC 小C的王者峡谷
Dilworth 定理
Docker's latest super detailed tutorial - docker creates, runs, and mounts MySQL
Log4qt memory leak, use of heob memory detection tool
关于大龄读博的几点回答?
5-整合swagger2
【WPF】通过动态/静态资源实现语言切换