使用ReentrantLock实现原子类业务操作

package com.alecor.Operate;


import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier;

/**
 * @author yuan_kf
 * @ClassName OperateBarrier
 * @Description 控制操作的唯一性,
 * @Version V1.0
 */

public class OperateBarrier {
    /**
     * Barriers
     */
    private static ConcurrentHashMap<String, Barrier> barrierMap = new ConcurrentHashMap<>();
    /**
     * Active time of barrier
     */
    private static final int BARRIER_EXIST_IN_SECONDS = 5;
    
    
    private static final Lock lock = new ReentrantLock();
    
    public static <R>R operate(Supplier<R> operate){
        try{
            lock.lock();
            // 同步执行
            return operate.get();
        }finally{
            lock.unlock();
        }
    }
    
    
    public static <R>R operateWait(String operateId, Supplier<R> operate){
        Barrier barrier = barrierMap.computeIfAbsent(operateId, key -> new Barrier(operateId));
        boolean signal = inQueue(barrier);
        try{
            // 同步执行
            return operate.get();
        }finally{
            deQueue(barrier, signal);
        }
    }
    
    private static boolean inQueue(Barrier barrier){
        boolean signal = true;
        barrier.barrierLock.lock();
        try {
            if(barrier.enQueueCount.get() > 0){
                // 当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态
                signal = barrier.enQueueCondition.await(BARRIER_EXIST_IN_SECONDS, TimeUnit.SECONDS);
            }
            barrier.enQueueCount.incrementAndGet();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            //Ignore
        } finally{
            barrier.barrierLock.unlock();
        }
        return signal;
    }
    
    private static void  deQueue(Barrier barrier, boolean signal){
        barrier.barrierLock.lock();
        try{
            if(barrier.enQueueCount.get() > 0 ){
                if(signal) {
                    // 释放阻塞的线程
                    barrier.enQueueCondition.signal();
                }
                barrier.enQueueCount.decrementAndGet();
            }
            if(!barrier.barrierLock.hasWaiters(barrier.enQueueCondition)) {
                barrierMap.remove(barrier.id);
            }
        }finally{
            barrier.barrierLock.unlock();
        }
    }
    private static class Barrier{
        
        private final ReentrantLock barrierLock;
        /**
         * In queue
         */
        private final Condition enQueueCondition;
        
        private String id;
        
        private final AtomicInteger enQueueCount = new AtomicInteger(0);
        Barrier(String id){
            this.id = id;
            barrierLock = new ReentrantLock();
            enQueueCondition = barrierLock.newCondition();
        }
    }
    
    
    public static void main(String[] args) {
    
        CountDownLatch countDownLatch = new CountDownLatch(100);
        for (int i = 1; i < 10; i++) {
            String finalNum =  "AAA" + "_";
            new Thread(() ->{
                // 5
                String result = OperateBarrier.operateWait( finalNum,() ->{
                    try {
                        System.out.println(Thread.currentThread().getName() + "   ->    " +finalNum);
                        Thread.sleep(1000);
                    } catch (InterruptedException exception) {
                        exception.printStackTrace();
                    }
                    return finalNum;
                });
                System.out.println(Thread.currentThread().getName()  +"-> result:" + result);
            }).start();
        }
    
        for (int i = 0; i < 100; i++) {
            countDownLatch.countDown();
            try {
                Thread.sleep(1000);
                System.out.println("countDownLatch "+ countDownLatch.getCount());
            } catch (InterruptedException exception) {
                exception.printStackTrace();
            }
        }
    
        try {
            countDownLatch.await();
        } catch (InterruptedException exception) {
            exception.printStackTrace();
        }
    
        System.out.println("endendendendendend");
    
    }
    
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值