婚庆公司网站怎么做,手机单页网站教程,网站使用什么数据库,网站开发需求文档模板带er图PostMan不是严格意义上的并发请求工具#xff0c;实际是串行的#xff0c;如果需要测试后台接口并发时程序的准确性#xff0c;建议采用JMeter工具。
案例#xff1a;JMeter设置20个并发卖票请求#xff0c;查看后台是否存在超卖的情况 方式一#xff1a;一共10张票实际是串行的如果需要测试后台接口并发时程序的准确性建议采用JMeter工具。
案例JMeter设置20个并发卖票请求查看后台是否存在超卖的情况 方式一一共10张票票余额作为成员属性放在控制器中没做任何的锁控制
package com.gingko.controller;
import com.gingko.common.GenericWebResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Random;RestController
RequestMapping(ticket)
Slf4j
public class TicketController {private static int TICKET_AMOUNT 10;//一共10张票PostMapping(/sell)public GenericWebResult sell() {GenericWebResult result null;if(TICKET_AMOUNT 0) {try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}TICKET_AMOUNT--;System.out.println(售票成功余票 TICKET_AMOUNT);result GenericWebResult.ok(售票成功余票,TICKET_AMOUNT);}else {result GenericWebResult.error(售票失败余票,TICKET_AMOUNT);System.out.println(售票失败余票 TICKET_AMOUNT);}return result;}
}运行结果及分析
从运行结果可以看出在高并发的时候出现了超卖和数据不一致的问题 方式二一共10张票票余额作为成员属性放在控制器中卖票的请求方法上加锁synchronized
package com.gingko.controller;
import com.gingko.common.GenericWebResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Random;RestController
RequestMapping(ticket)
Slf4j
public class TicketController {private static int TICKET_AMOUNT 10;//一共10张票PostMapping(/sell)public synchronized GenericWebResult sell() {GenericWebResult result null;if(TICKET_AMOUNT 0) {try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}TICKET_AMOUNT--;System.out.println(售票成功余票 TICKET_AMOUNT);result GenericWebResult.ok(售票成功余票,TICKET_AMOUNT);}else {result GenericWebResult.error(售票失败余票,TICKET_AMOUNT);System.out.println(售票失败余票 TICKET_AMOUNT);}return result;}
}运行结果及分析 从运行结果可以看出在高并发的时候没有出现超卖或数据不一致问题数据结果符合预期。
方式三TicketController对象多例并且TICKET_AMOUNT属性不是static每个对象各自持有
package com.gingko.controller;
import com.gingko.common.GenericWebResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Random;RestController
RequestMapping(ticket)
Slf4j
Scope(prototype) //多例
public class TicketController {private int TICKET_AMOUNT 10;PostMapping(/sell)public GenericWebResult sell() {GenericWebResult result null;if(TICKET_AMOUNT 0) {try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}TICKET_AMOUNT--;System.out.println(售票成功余票 TICKET_AMOUNT);result GenericWebResult.ok(售票成功余票,TICKET_AMOUNT);}else {result GenericWebResult.error(售票失败余票,TICKET_AMOUNT);System.out.println(售票失败余票 TICKET_AMOUNT);}return result;}
}运行结果及分析 从程序可以看出20个并发请求后台生成了20个TicketController实例每个实例内部都持有属性TICKET_AMOUNT 10sell方法执行后TICKET_AMOUNT 9
方式一、方式二与方式三示意图区别如下
方式一、二堆内存中只有一个TicketController实例并且TICKET_AMOUNT不属于实例对象属于共享的数据区对这种共享数据并发操作时需要锁机制控制防止出现数据不一致。
方式三并发请求多少堆内存中生成多少个TicketController实例并且每个TicketController实例各自持有TICKET_AMOUNT访问各自的成员属性也就不会发生数据不一致问题。