ReentrantLock锁使用记录

lock、tryLock和lockInterruptibly的差別:

java中ReentrantLock下有三个获取所得方法:
lock():若lock被thread A取得,thread B会进入block狀態,直到取得lock;
tryLock():若当下不能取得lock,thread就会放弃,可以设置一个超时时间参数,等待多久获取不到锁就放弃;
lockInterruptibly():跟lock()情況一下,但是thread B可以通过interrupt被唤醒处理InterruptedException异常。

在根据业务属性在同一业务中开不同线程进行处理:


    private static Map<String,Lock> reentrantLockMap = null;
    public static Map<String,Lock> getReentrantLockMap(){
        return reentrantLockMap;
    }

//初始锁
static{
                reentrantLockMap = new HashMap<String,Lock>();
                for (DataSyncEntity dataSyncEntity : datList) {
                      try {
                                /**根据要处理的表数量初始锁的数量,用于分业务进行上传数据的时候加锁使用**/
                                Lock newLock2 = new ReentrantLock();
                                reentrantLockMap.put(dataSyncEntity.getClassName()+"_mysend", newLock2);

                        }

                }

}

//业务中使用锁

public void sendCacheData(){
        /*根据系统配置执行不同的方案,
         * 配置为1,代表使用原有方案
         * (每次定时任务向上级平台发送一条缓存数据
          * 配置为2,代表使用新的缓存数据发送方案(根据配置批量发送多条缓存数据)
         */
        try {
            logger.info(String.format("sendCacheData:发送缓存定时器启动,定时器执行时间:%s", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime())));
            if (DataSyncCacheManager.DATA_SYNC_STRATEGY_NEW.equals(dataSyncStrategy)) {
                /**2022-6-28修改为定时给每个业务启动上传线程sendCacheData进行数据上传,并且保证单业务的线程安全;**/
                if (DataSyncHistoryManager.getDataSync() !=null && DataSyncHistoryManager.getDataSync().getClassNames() != null && DataSyncHistoryManager.getDataSync().getClassNames().size() >0 ) {
                    for (final DataSyncEntity nowSyncEntity : DataSyncHistoryManager.getDataSync().getClassNames()){
                        cacheThreadPool.execute(new Runnable(){
                            @Override
                            public void run() {
                                if(null!=DataSyncHistoryManager.getReentrantLockMap()){
                                    //获取上传锁
                                    Lock lock = DataSyncHistoryManager.getReentrantLockMap().get(nowSyncEntity.getClassName()+"_mysend");
                                    //尝试拿到锁
                                    if(null!=lock && lock.tryLock()) { 
                                        try {
                                            dataSyncCacheManager.sendData(nowSyncEntity.getClassName());
                                        } catch (Exception e) {
                                            logger.info("同步数据失败" + e.getMessage(),e);
                                        } finally {
                                            lock.unlock();//释放锁
                                        }
                                    }else{
                                        logger.info("获取锁【"+nowSyncEntity.getClassName()+"】失败,稍后继续获取");
                                    }
                                }
                            }
                        });
                    }
                }else{
                    logger.info("加载上传类异常:"+(null!=DataSyncHistoryManager.getDataSync()?JsonUtil.toJson(DataSyncHistoryManager.getDataSync()):""));
                }
            } else {
                sendData();
            }
        } catch (Exception e) {
            logger.info("启动线程异常:"+e.getMessage(),e);
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ReentrantLockJava中的一个可重入,它提供了与synchronized关键字类似的功能,但更加灵活和强大。下面是一些与ReentrantLock相关的面试题及其答案: 1. 什么是可重入? 可重入是指同一个线程可以多次获得同一个,而不会造成死。ReentrantLock就是一个可重入。 2. ReentrantLock相对于synchronized关键字有什么优势? 相对于synchronized关键字,ReentrantLock提供了更多的功能和灵活性。它可以实现公平和非公平,支持多个条件变量,可以中断等待的线程,还可以尝试获取等。 3. ReentrantLock如何实现可重入性? ReentrantLock通过记录持有的线程和持有次数来实现可重入性。当一个线程再次获取已经持有的时,它的持有次数会增加,当释放时,持有次数会减少,只有当持有次数为0时,其他线程才能获取该。 4. ReentrantLock如何实现公平性和非公平性? ReentrantLock可以通过构造函数来指定是公平还是非公平。公平会按照线程请求的顺序来获取,而非公平则允许插队,可能会导致某些线程一直获取不到。 5. ReentrantLock如何实现条件变量? ReentrantLock提供了Condition接口来支持条件变量。通过调用ReentrantLock的newCondition()方法可以创建一个Condition对象,然后可以使用该对象的await()、signal()和signalAll()方法来实现线程的等待和唤醒。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值