@RequestMapping("/test")
@RestController
public class TestController {
ConcurrentHashMap<String, Goods> goodsMap = new ConcurrentHashMap<>();
/**
* 下单
*
* @return
*/
@RequestMapping("/placeOrder")
public ResponseEntity test(String id) {
System.out.println("正在下单:商品主键为:" + id);
//初始化商品
if (goodsMap.get(id) == null) {
return ResponseEntity.status(500).body("下单商品不存在!");
} else {
return goodsMap.get(id).placeOrder();
}
}
@RequestMapping("init")
@PostConstruct
public ResponseEntity init() {
try {
//随机创建商品
Goods goods = new Goods();
goods.setCount(ThreadLocalRandom.current().nextInt(100));
goodsMap.put(Thread.currentThread().getId() + "", goods);
System.out.println("商品主键:" + Thread.currentThread().getId() + "商品初始化数量为:" + goods.getCount());
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(500).body("初始化库存失败");
}
return ResponseEntity.ok("初始化成功" + JSON.toJSONString(goodsMap));
}
class Goods {
/**
* 令牌 -- 可重入锁
*/
ReentrantLock lock = new ReentrantLock();
private Integer count = 0;//共享变量 库存
/**
* 用于模拟数据库查询延迟
*
* @return
* @throws InterruptedException
*/
public Integer getCount() throws InterruptedException {
Thread.sleep(ThreadLocalRandom.current().nextInt(200)); //模拟数据库延迟
return count;
}
/**
* 用于模拟数据库写入延迟
*
* @return
* @throws InterruptedException
*/
public void setCount(Integer count) throws InterruptedException {
Thread.sleep(ThreadLocalRandom.current().nextInt(200)); //模拟数据库延迟
this.count = count;
}
/**
* 出库
*
* @throws InterruptedException
*/
public void stockRemoval() throws InterruptedException {
this.setCount(this.getCount() - 1);
System.out.println(Thread.currentThread().getName() + "下单成功!剩余数量" + getCount());
}
/**
* 商品下单
*
* @return
*/
ResponseEntity placeOrder() {
//判断当前线程是否是持有令牌者
//进来先锁住线程 避免资源共享
//尝试获取锁 如果为TRUE 表示锁未被占用 如果为False 则锁已经被其他线程占用
if (lock.tryLock()) {
try {
//判断当前库存是否大于0
Integer count = getCount();
System.out.println("正在下单 当前库存为" + count);
if (count > 0) {
//商品出库
stockRemoval();
// Thread.sleep(3000); //模仿处理时间 锁死3秒 把其他的线程排除在外
return ResponseEntity.ok("下单成功!");
} else {
return ResponseEntity.status(500).body("库存不足!");
}
} catch (Exception exception) {
exception.printStackTrace();
return ResponseEntity.status(500).body("系统异常");
} finally {
//操作到最后都要释放锁 避免死锁
lock.unlock();
}
} else {
//未持有线程令牌者 直接响应 避免排队等待
return ResponseEntity.status(500).body("下单人数过多,可以等待一段时间再下单");
}
}
}
}
拒绝线程等待,增加用户体验