java 利用cas算法模拟多线程并发抢票

利用cas算法实现。基于乐观锁。如果值发生冲突。加入异步线程递归进行抢(设置递归次数。防止死循环)

1、创建ThreadUtils类

/**
 * 线程副本,保证数据
 */
public class ThreadUtils {
    private static ThreadLocal<Integer> threadLocal;
    static{
        threadLocal = new ThreadLocal();
    }

    public static void set(int value){
        threadLocal.set(value);
    }

    public static Integer get(){
        return threadLocal.get();
    }
}

2、创建CasUtils类

/**
 * 基于cas原理实现高并发
 */
public class CasUtils implements Runnable{
    /**
      * 私有内部类创建单例
     */
    private static class AtomicHolder{
        private static volatile AtomicInteger s = new AtomicInteger(ThreadUtils.get());
    }

    /**
     * 线程池
     */
    private  static ThreadPoolExecutor ex;
    static {
         ex = new ThreadPoolExecutor(
                10,10,5,TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(1),
                new ThreadPoolExecutor.DiscardOldestPolicy());

    }

    public CasUtils()throws Exception{
        int value = ThreadUtils.get();
        if(!AtomicHolder.s.compareAndSet(value,value)){
            /**
             * 此处对于未赋值的进行其他操作
             */
        }
    }

    @Override
    public void run() {
        System.out.println("我在抢票中..."+Thread.currentThread());
        try {
            int value = AtomicHolder.s.get();
            int si = 0;
            if(value-1>=0&&(si=AtomicHolder.s.decrementAndGet())>0){
                /**
                 * 涉及业务可以写入消息队列
                 */
                System.out.println("抢票成功..."+Thread.currentThread()+"========"+(si));
            }else{
                /*if(value-1<0){
                    System.out.println("暂无票..."+Thread.currentThread()+"========"+(si));
                    return;
                }*/
                ex.execute(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("抢票循环..."+Thread.currentThread());
                        boolean isSubmit = true;
                        //设置抢票循环次数。
                        int time = 0;
                        while(isSubmit){
                            ++time;
                            int value = AtomicHolder.s.get();
                            //超过10次结束
                            if(time>=10){
                                System.out.println("抢票结束【未抢到】..."+Thread.currentThread());
                                isSubmit = false;
                                break;
                            }
                            if(value-1>=0&&AtomicHolder.s.decrementAndGet()>0){
                                /**
                                 * 涉及业务可以写入消息队列
                                 */
                                isSubmit = false;
                                System.out.println("抢票成功..."+Thread.currentThread());
                            }
                            try {
                                Thread.sleep(200);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                });
            }
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
3、执行
public static void main(String[] args) throws Exception {
    for(int i=0;i<100;i++){
        ThreadUtils.set(10);
        new Thread( new CasUtils()).start();
    }
}

猜你喜欢

转载自blog.csdn.net/saygood999/article/details/106946527