diff --git a/spring-boot-demo-zookeeper/src/main/java/com/xkcoding/zookeeper/controller/TestController.java b/spring-boot-demo-zookeeper/src/main/java/com/xkcoding/zookeeper/controller/TestController.java deleted file mode 100644 index 3db3ac6..0000000 --- a/spring-boot-demo-zookeeper/src/main/java/com/xkcoding/zookeeper/controller/TestController.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.xkcoding.zookeeper.controller; - -import cn.hutool.core.lang.Dict; -import com.xkcoding.zookeeper.annotation.LockKeyParam; -import com.xkcoding.zookeeper.annotation.ZooLock; -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.util.concurrent.TimeUnit; - -/** - *

- * 测试Controller - *

- * - * @package: com.xkcoding.zookeeper.controller - * @description: 测试Controller - * @author: yangkai.shen - * @date: Created in 2018-12-27 15:51 - * @copyright: Copyright (c) 2018 - * @version: V1.0 - * @modified: yangkai.shen - */ -@RestController -@Slf4j -public class TestController { - - @GetMapping("/buy") - public Dict buy(int userId) throws InterruptedException { - log.info("{} 购买中。。。", userId); - doBuy(userId); - return Dict.create().set("flag", true).set("msg", "秒杀成功").set("data", userId); - } - - @ZooLock(key = "buy", timeout = 1, timeUnit = TimeUnit.MINUTES) - private void doBuy(@LockKeyParam int userId) throws InterruptedException { - log.info("{} 正在出库。。。", userId); - TimeUnit.SECONDS.sleep(5); - log.info("{} 扣库存成功。。。", userId); - } -} diff --git a/spring-boot-demo-zookeeper/src/test/java/com/xkcoding/zookeeper/SpringBootDemoZookeeperApplicationTests.java b/spring-boot-demo-zookeeper/src/test/java/com/xkcoding/zookeeper/SpringBootDemoZookeeperApplicationTests.java index 20b49c9..a2b30d7 100644 --- a/spring-boot-demo-zookeeper/src/test/java/com/xkcoding/zookeeper/SpringBootDemoZookeeperApplicationTests.java +++ b/spring-boot-demo-zookeeper/src/test/java/com/xkcoding/zookeeper/SpringBootDemoZookeeperApplicationTests.java @@ -1,16 +1,101 @@ package com.xkcoding.zookeeper; +import com.xkcoding.zookeeper.annotation.ZooLock; +import com.xkcoding.zookeeper.aspectj.ZooLockAspect; +import lombok.extern.slf4j.Slf4j; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.recipes.locks.InterProcessMutex; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.aop.aspectj.annotation.AspectJProxyFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.stream.IntStream; + @RunWith(SpringRunner.class) @SpringBootTest +@Slf4j public class SpringBootDemoZookeeperApplicationTests { + public Integer getCount() { + return count; + } + + private Integer count = 10000; + private ExecutorService executorService = Executors.newFixedThreadPool(1000); + + @Autowired + private CuratorFramework zkClient; + + /** + * 不使用分布式锁,程序结束查看count的值是否为0 + */ @Test - public void contextLoads() { + public void test() throws InterruptedException { + IntStream.range(0, 10000).forEach(i -> executorService.execute(this::doBuy)); + TimeUnit.MINUTES.sleep(1); + log.error("count值为{}", count); + } + + /** + * 测试AOP分布式锁 + */ + @Test + public void testAopLock() throws InterruptedException { + // 测试类中使用AOP需要手动代理 + SpringBootDemoZookeeperApplicationTests target = new SpringBootDemoZookeeperApplicationTests(); + AspectJProxyFactory factory = new AspectJProxyFactory(target); + ZooLockAspect aspect = new ZooLockAspect(zkClient); + factory.addAspect(aspect); + SpringBootDemoZookeeperApplicationTests proxy = factory.getProxy(); + IntStream.range(0, 10000).forEach(i -> executorService.execute(() -> proxy.aopBuy(i))); + TimeUnit.MINUTES.sleep(1); + log.error("count值为{}", proxy.getCount()); + } + + /** + * 测试手动加锁 + */ + @Test + public void testManualLock() throws InterruptedException { + IntStream.range(0, 10000).forEach(i -> executorService.execute(this::manualBuy)); + TimeUnit.MINUTES.sleep(1); + log.error("count值为{}", count); + } + + @ZooLock(key = "buy", timeout = 1, timeUnit = TimeUnit.MINUTES) + public void aopBuy(int userId) { + log.info("{} 正在出库。。。", userId); + doBuy(); + log.info("{} 扣库存成功。。。", userId); + } + + public void manualBuy() { + String lockPath = "/buy"; + log.info("try to buy sth."); + try { + InterProcessMutex lock = new InterProcessMutex(zkClient, lockPath); + try { + if (lock.acquire(1, TimeUnit.MINUTES)) { + doBuy(); + log.info("buy successfully!"); + } + } finally { + lock.release(); + } + } catch (Exception e) { + log.error("zk error"); + } + } + + public void doBuy() { + count--; + log.info("count值为{}", count); } }