项目中执行lock.unlock()出现java.lang.IllegalMonitorStateException

项目中代码,这段代码是判断excel是不是正在导出中,并发量只允许为1,因为excel导出很占cpu资源

@RequestMapping("excelOrderExportCheck.json")
  @ResponseBody
  public AjaxObj excelOrderExportCheck(){
  AjaxObj ajaxObj=new AjaxObj();
  //防止重复excel导出
  long exportTime = orderCarMallUtil.getExportRedisTime(REDISNAME);
    if(lock.tryLock() //这里尝试获取锁){
        ajaxObj.setResult(AjaxObj.SUCCESS); 
        ajaxObj.setMsg("exportTime="+exportTime+",System.currentTimeMillis()-exportTime="+(System.currentTimeMillis()-exportTime));
        }else{
            ajaxObj.setMsg("有人正在导出中,请不要重复导出");
            ajaxObj.setResult(AjaxObj.FAILD);
        }
        return ajaxObj;
    }
 /**
     * 导出详细定单
     * @param queryObj
     * @param response
     */
    @RequestMapping("/excelOrderExport.json")
    public void excelOrderExport(PreOrderQueryOperateParamDTO queryParam , HttpServletResponse response) {
        queryParam.setSourceId(CSCConstants.SOURCEID_CARMALL);
        logger.info("excelOrderExport queryParam:{}",JSONObject.toJSONString(queryParam));
        String[] head = new String[] { "定单编号", "商品编号", "车源经销商代码","车源经销商名称","代交车经销商名称", "车型名称", "车辆来源", "定单状态", "交车方式", "物流状态"
                , "经销商跟进状态","支付状态","定单处理状态","有无礼包","用户名","用户编号","车主姓名","车主手机","下单时间","三合一审核状态","二合一审核状态","发票金额"
                , "定单进度", "礼包内容", "品牌","车系名称","颜色","VIN码","金融方案名称","保险方案名称" ,"礼包名称","定单类型","定单渠道","定单备注","结算标识","身份证号"
                , "发票类型", "发票抬头", "企业机构代码", "审核通过时间","券金额","定金","已支付总额","套装送货地址"};
        try {
            int oneHour = 1000 * 60 * 60;
            //防止重复excel导出
            long exportTime = orderCarMallUtil.getExportRedisTime(REDISNAME);
            if(exportTime==0 || System.currentTimeMillis()-exportTime>oneHour){

            }else{
                return;
            }
            long startTimeMillis = System.currentTimeMillis();
            orderCarMallUtil.setExportRedisTime(REDISNAME, startTimeMillis);
            List<OrderManagerVo> voList = getVoList(queryParam);
            orderCarMallUtil.setExportRedisTime(REDISNAME, 0L);
            logger.info("excelOrderExport size:{}",voList.size());
            //exportExcelService.excelExoprt(head, null, voList, null, "order", response,CSCConstants.DATE_FORMART_STRING2);
            //exportXSSFWorkExcelService.excelExoprt(head, null, voList, null, "order", response,CSCConstants.DATE_FORMART_STRING2);
            csvWriterUtil.csvWrite(head, voList, "order", response, CSCConstants.DATE_FORMART_STRING2);
            //orderCarMallUtil.setExportRedisTime(REDISNAME, 0L);
            //exportExcelService.excelExoprt(head, null, voList, null, "order", response,CSCConstants.DATE_FORMART_STRING2);
            //exportXSSFWorkExcelService.excelExoprt(head, null, voList, null, "order", response,CSCConstants.DATE_FORMART_STRING2);
            long endTimeMillis = System.currentTimeMillis();
            logger.info("excelOrderExport time consuming:{}",(endTimeMillis-startTimeMillis));

        } catch (IllegalArgumentException | SecurityException e) {
            orderCarMallUtil.setExportRedisTime(REDISNAME, 0L);
            logger.error("call exportExcelService excelExoprt message:{}",e.getMessage());
        } catch (Exception e2){
            orderCarMallUtil.setExportRedisTime(REDISNAME, 0L);
            logger.error("call exportExcelService excelExoprt message:{}",e2.getMessage());
        }
        finally{
           lock.unlock();//导出完之后给上面代码获取到的锁解锁
        }
    }

报出如下异常:
这里写图片描述

看了下源码是在155行抛出的异常:

这里写图片描述
执行lock.unlock()执行源码会判断当前线程有没有获取到锁,如果没获取到锁就解锁会
抛出 new IllegalMonitorStateException();

所以我的问题是当前线程加的锁只能在当前线程中进行解锁,不能再其他线程中进行解锁。

猜你喜欢

转载自blog.csdn.net/CSDNzhangtao5/article/details/66970326
今日推荐