package com.liquidnet.service.example.controller;

import com.liquidnet.common.cache.redisson.util.RedisLockUtil;
import com.liquidnet.common.swagger.config.SwaggerApiVersion;
import com.liquidnet.service.base.ResponseDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @author AnJiabin <jiabin.an@lightnet.io>
 * @version V1.0
 * @Description: redis分布式锁控制器
 * @class: RedissonLockController
 * @Package com.liquidnet.service.example.controller
 * @Copyright: LightNet @ Copyright (c) 2020
 * @date 2020/9/11 16:20
 */
@RestController
@Api(tags = "redisson", description = "redis分布式锁控制器" )
@RequestMapping("/redisson" )
public class RedissonLockController {
    public static final Logger log = LoggerFactory.getLogger(RedissonLockController.class);
    /**
     * 锁测试共享变量
     */
    private Integer lockCount = 100;

    /**
     * 无锁测试共享变量
     */
    private Integer count = 100;

    /**
     * 模拟线程数
     */
    private static int threadNum = 10;

    /**
     * 模拟并发测试加锁和不加锁
     * @return
     */
    @GetMapping("/test")
    @ApiOperation(value = "模拟并发测试加锁和不加锁")
    public void lock(){
        // 计数器
        final CountDownLatch countDownLatch = new CountDownLatch(1);
        for (int i = 0; i < threadNum; i ++) {
            MyRunnable myRunnable = new MyRunnable(countDownLatch);
            Thread myThread = new Thread(myRunnable);
            myThread.start();
        }
        // 释放所有线程
        countDownLatch.countDown();
    }

    /**
     * 加锁测试
     */
    private void testLockCount() {
//        String lockKey = "lock-test";
//        try {
//            // 加锁，设置超时时间2s
//            RedisLockUtil.lock(lockKey,2, TimeUnit.SECONDS);
//            lockCount--;
//            log.info("lockCount值："+lockCount);
//        }catch (Exception e){
//            log.error(e.getMessage(),e);
//        }finally {
//            // 释放锁
//            RedisLockUtil.unlock(lockKey);
//        }
    }

    /**
     * 无锁测试
     */
    private void testCount() {
        count--;
        log.info("count值："+count);
    }


    public class MyRunnable implements Runnable {
        /**
         * 计数器
         */
        final CountDownLatch countDownLatch;

        public MyRunnable(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                // 阻塞当前线程，直到计时器的值为0
                countDownLatch.await();
            } catch (InterruptedException e) {
                log.error(e.getMessage(),e);
            }
            // 无锁操作
            testCount();
            // 加锁操作
            testLockCount();
        }

    }




    @ApiOperation(value = "国家代码")
    @GetMapping("/list_country")
    public ResponseDto listCountry() {



        String key = "lock-test-1111";
        RLock lock = RedisLockUtil.lock(key);
        System.out.println("直接加锁" + lock.isLocked());

        boolean b = RedisLockUtil.tryLock(key, 1, 10);
        System.out.println("尝试获取锁" + b);
        return null;
    }

}
