40.安心技术梳理 - 闭锁(CountDownLatch)进行多线程发送优惠券实现

1.满足多人并发,每人固定处里数的最终一致性

public static int handle(Integer a){
        System.out.println("发送优惠券"+a);
        return a;
    }
    
    public static void main(String[] args) throws InterruptedException {
        //优惠券集合
        List list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        //闭锁发送优惠券
        Map map = new HashMap<>();
        final List flags = new ArrayList<>();
        final List member = new ArrayList<>();
        final CountDownLatch cancelDownLatch = new CountDownLatch(3);
        for(Integer a : list){
            new Thread(() -> {
                int num = handle(a);
                if(num<3){
                    flags.add(false);
                }else{
                    member.add(num);
                }
                cancelDownLatch.countDown();
            }).start();
        }
    cancelDownLatch.await();
    //是否全部发送成功
    map.put("status",(CollectionUtils.isEmpty(flags))?1:0);
    map.put("coupons",list);
    System.out.println(map.toString());
}

2.满足多人并发抢购数据

import java.math.BigDecimal;
import java.util.Stack;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class PersonMain {
    /**
     * 100张优惠劵
     */
    private static final Stack COUPON_ALL = new Stack<>();
    /**
     * 发送优惠劵线程池
     */
    private static ThreadPoolExecutor THREAD_COUPON_POOL_EXECUTOR = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
            Runtime.getRuntime().availableProcessors() + 10, 10,
            TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(100), new BasicThreadFactory.Builder().namingPattern("send-coupon-multi-thread-%d").build(),
            new ThreadPoolExecutor.DiscardPolicy());

    static {
        //初始化优惠劵钱数
        for (int i = 1; i <= 100; i++) {
            COUPON_ALL.add(new BigDecimal(i));
        }
    }

    public static void main(String[] args) throws InterruptedException {
        //1000个人同时抢优惠劵 多余的将拒绝
        int personNum = 1000;
        CountDownLatch startCountDownLatch = new CountDownLatch(1);
        //卷的个数初始化闭锁
        CountDownLatch endCountDownLatch = new CountDownLatch(COUPON_ALL.size());
        for (int i = 0; i < personNum; i++) {
            THREAD_COUPON_POOL_EXECUTOR.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 使线程在此等待,当开始门打开时,一起涌入门中
                        startCountDownLatch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(System.currentTimeMillis() + " [" + Thread.currentThread() + "] get coupon[" + COUPON_ALL.pop() + "]");
                }
            });
            // 将结束门减1,减到0时,就可以开启结束门了
            endCountDownLatch.countDown();
        }

        long startTime = System.nanoTime();
        System.out.println(startTime + " [" + Thread.currentThread() + "] All thread is ready, concurrent going...");
        //开始发送
        startCountDownLatch.countDown();
        //等待所有卷都发送完
        endCountDownLatch.await();
        long endTime = System.nanoTime();
        System.out.println(endTime + " [" + Thread.currentThread() + "] All thread is completed.");
        THREAD_COUPON_POOL_EXECUTOR.allowCoreThreadTimeOut(true);
        if (THREAD_COUPON_POOL_EXECUTOR.isShutdown()) {
            THREAD_COUPON_POOL_EXECUTOR.shutdown();
        }
    }

}

你可能感兴趣的:(安心技术)