java 实现 类似 reids  nx锁   , 模拟秒杀操作

依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>23.0</version>
</dependency>

 

package com.sea.shop.common.util;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/***************************
 *<pre>
 * @Project Name : shop_research
 * @Package      : com.sea.shop.common.util
 * @File Name    : MyNxLockUtils
 * @Author       :  Sea
 * @Date         : 7/26/22 11:46 AM
 * @Purpose      :
 * @History      :
 *</pre>
 ***************************/
public class MyNxLockUtils {

    private static volatite String  lcPoint0="xx0";
    private static valatite String  lcPoint1="xx1";
    private static valatite String  lcPoint2="xx2";
    private static volatile String  lcPoint3="xx3";
    private static volatite String  lcPoint4="xx4";
    private static volatite String  lcPoint5="xx5";
    private static volatite String  lcPoint6="xx6";
    private static volatite String  lcPoint7="xx7";
    private static volatite String  lcPoint8="xx8";
    private static volatite String  lcPoint9="xx9";

    /**
     * 分段枷锁,提升效率
     * @param k
     * @return
     */
    private static String getLcPoint(String k){
        switch (k.hashCode()%10){
            case 1: return lcPoint1;
            case 2: return lcPoint2;
            case 3: return lcPoint3;
            case 4: return lcPoint4;
            case 5: return lcPoint5;
            case 6: return lcPoint6;
            case 7: return lcPoint7;
            case 8: return lcPoint8;
            case 9: return lcPoint9;
            default: return lcPoint0;
        }
    }

    private static  Cache<String, String> lockCache = null;
    static {
        lockCache =  CacheBuilder.newBuilder().expireAfterWrite(12, TimeUnit.SECONDS).build();
    }

    /**
     * @param k
     * @param v
     * @return
     */
    public static Boolean getLock(String k, String v){
        if(lockCache.getIfPresent(k)==null)
        {
            synchronized (getLcPoint(k)){
                if(lockCache.getIfPresent(k)==null){
                    lockCache.put(k,v);
                    return true;
                }
            }
        }
        return false;
    }

    public static  void unlock(String k, String v)
    {
        String ifPresent = lockCache.getIfPresent(k);
        if(ifPresent!=null&&ifPresent.equals(v)){
            lockCache.invalidate(k);
        }
    }

    /**
     * @param k
     * @param v
     * @param acquireTimeOutSec
     * @return
     */
    public static  Boolean getLock(String k, String v,Long acquireTimeOutSec){
        long expTime = System.currentTimeMillis()+ TimeUnit.SECONDS.toMillis(acquireTimeOutSec);
        while (true)
        {
            try {
                Boolean lock = getLock(k, v);
                if(lock)
                {
                    return true;
                }
                Thread.sleep(15l);
                if(System.currentTimeMillis()-expTime>0){
                    return  false;
                }
            }catch (Exception e)
            {
                return  false;
            }
        }
    }




    //模拟库存
    private static  volatile int  no =1000;
    public static void main(String[] args) {
        ExecutorService cachePool = Executors.newFixedThreadPool(32);
        long start = System.currentTimeMillis();
        int threadNo = 100;
        for(int i=1;i<=threadNo;i++)
        {
            cachePool.submit(()->
            {
                Boolean lock = false;
                while (true)
                {
                    lock = getLock("1", "1");
                    if(lock)
                    {
                        try
                        {
                            int myNo = no--; //扣减库存
                            Thread.sleep(100);
                            System.err.println(myNo);
                            unlock("1","1");
                            break;
                        } catch (InterruptedException e)
                        {
                            e.printStackTrace();
                            unlock("1","1");
                        }

                    }
                }
            });
        }
        ThreadPoolExecutor cachePool1 = (ThreadPoolExecutor) cachePool;
        while (true){
            long completedTaskCount = cachePool1.getCompletedTaskCount();
            if(completedTaskCount==threadNo){
                System.err.println("last no is :"+ no);
                System.err.println("total cost time :"+(System.currentTimeMillis()-start));
                break;
            }
        }
    }

}

 

posted on 2022-07-26 16:13  lshan  阅读(36)  评论(0编辑  收藏  举报