package com.yf.service; import com.yf.dao.GoodUserDao; import com.yf.dao.GoodsDao; import com.yf.pojo.GoodUser; import com.yf.util.RedisPoolUtil; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import redis.clients.jedis.Jedis; import java.util.List; @Service public class GoodUserService { @Autowired private GoodUserDao goodUserDao; @Autowired private GoodsDao goodsDao; public static Logger logger = Logger.getLogger(GoodUserService.class); public List<GoodUser> getGoods() { List<GoodUser> goods = goodUserDao.getAllGoodUser(); return goods; } //保存 public void saveGoods(GoodUser goodUser){ goodUserDao.saveGoods(goodUser); } //1 判断条件 public boolean isKill(String userName){ Jedis jedis=RedisPoolUtil.getConn(); //限制用户操作频率 10秒内 String value=jedis.set(userName,"","NX","EX",10); if(!"OK".equals(value)){ logger.warn("此用户重复请求"); jedis.close(); return false; } String token=jedis.lpop("token_list1"); logger.info(userName+"拿到令牌"); if(null==token||"".equals(token)){ logger.info("令牌发完"); jedis.close(); return false; } return true; } //秒杀1.减少数量 2.插入用户记录 public void killGood(String userName){ if(isKill(userName)){ GoodUser goodUser=new GoodUser(); goodUser.setName(userName); goodUser.setGoodsName("phone"); int i=goodsDao.minusNum("phone"); if(i>0){ goodUserDao.saveGoods(goodUser); logger.info(userName+" 秒杀成功"); } } } }
package com.yf.service; import com.yf.pojo.GoodUser; import com.yf.testMain; import com.yf.util.RedisPoolUtil; import org.apache.log4j.Logger; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import redis.clients.jedis.Jedis; import java.util.List; import java.util.concurrent.CountDownLatch; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = testMain.class) public class GoodsServiceTest { @Autowired private GoodsService goodsService; @Autowired private GoodUserService goodUserService; public static Logger logger = Logger.getLogger(GoodsServiceTest.class); private static final int threadNum=1000; private CountDownLatch cdl=new CountDownLatch(threadNum); @Test public void testGet() { List<GoodUser> goods=goodUserService.getGoods(); for (GoodUser gu:goods){ System.out.println(gu.getGoodsName()); } } @Test public void testSave() { GoodUser goodUser=new GoodUser(); goodUser.setName("yf"); goodUser.setGoodsName("bike"); goodUserService.saveGoods(goodUser); } @Test public void testMinus() { goodsService.minusNum("bike"); } @Before public void start(){ RedisPoolUtil.initialPool(); Jedis jedis=RedisPoolUtil.getConn(); for(int i=0;i<20;i++){ jedis.lpush("token_list1",""+i); } jedis.close(); logger.info("令牌预先生成完毕"); logger.info("开始测试"); } @Test public void testKill() { try { Thread[] threads=new Thread[threadNum]; for(int i=0;i<threadNum;i++){ logger.info("循环"+i+"次"); Thread thread=new Thread(new userRequest("yf"+i)); threads[i]=thread; thread.start(); cdl.countDown(); } for(Thread thread:threads){ thread.join(); } }catch (Exception e){ e.printStackTrace(); }finally { RedisPoolUtil.closePool(); } } class userRequest implements Runnable{ String userName; public userRequest(String userName) { this.userName = userName; } @Override public void run() { try { cdl.await(); } catch (InterruptedException e) { e.printStackTrace(); } goodUserService.killGood(userName); } } }
3.令牌机制限定连接数据库的数量
String token=jedis.lpop("token_list1"); logger.info(userName+"拿到令牌"); if(null==token||"".equals(token)){ logger.info("令牌发完"); jedis.close(); return false; }