// @Scheduled(cron="0 */1 * * * ?")//(每隔1分鍾的整數倍) public void closeOrderTaskV2(){ System.out.println("關閉訂單定時任務啟動"); long lockTimeout = 5000;//鎖存在的時間 這個時間根據具體業務處理時間來設置 Long setnxResult = RedisShardedPoolUtil.setnx(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTimeout)); if(setnxResult != null && setnxResult.intValue() == 1){//如果返回值是1,代表設置成功,獲取鎖。假設程序執行到這里,此時關掉服務器 那么這里有可能出現死鎖的問題 RedisShardedPoolUtil.expire(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,5);//有效期5秒,防止死鎖(這里的鎖有效期,與上面的lockTimeout值必須統一) System.out.println("-----------業務方法開始---------"); System.out.println("執行業務方法"); System.out.println("-----------業務方法結束---------"); RedisShardedPoolUtil.del(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);//業務方法執行完之后 手動將鎖撤銷 }else{ System.out.println("未獲得分布式鎖,鎖名是:"+Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK); } System.out.println("關閉訂單定時任務結束"); } @Scheduled(cron="0 */1 * * * ?")//(每隔1分鍾的整數倍) public void closeOrderTaskV3(){ System.out.println("關閉訂單定時任務啟動"); long lockTimeout = 5000;//鎖存在的時間 這個時間根據具體業務處理時間來設置 Long setnxResult = RedisShardedPoolUtil.setnx(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTimeout)); if(setnxResult != null && setnxResult.intValue() == 1){ RedisShardedPoolUtil.expire(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,5);//有效期5秒,防止死鎖(這里的鎖有效期,與上面的lockTimeout值必須統一) System.out.println("-----------業務方法開始---------"); System.out.println("執行業務方法"); System.out.println("-----------業務方法結束---------"); RedisShardedPoolUtil.del(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK); }else{ //未獲取到鎖,那么繼續判斷,判斷時間戳與當前時間對比,看是否可以重置並獲取到鎖 String lockValueStr = RedisShardedPoolUtil.get(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK); if(lockValueStr ==null||lockValueStr != null && System.currentTimeMillis() > Long.parseLong(lockValueStr)){//這種到老鎖存在但是已經超時的情況一般是上面遇到的死鎖情況 //設置新鎖 並獲取老鎖的值,getset是一個原子性的方法 String getSetResult = RedisShardedPoolUtil.getSet(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTimeout)); if(getSetResult == null || (getSetResult != null && StringUtils.equals(lockValueStr,getSetResult))){//老鎖消失 或者老鎖過期並且老鎖未被其他進程操作的情況下 有權利獲取鎖 //真正獲取到鎖 RedisShardedPoolUtil.expire(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,5);//有效期5秒,防止死鎖 System.out.println("-----------業務方法開始---------"); System.out.println("執行業務方法"); System.out.println("-----------業務方法結束---------"); RedisShardedPoolUtil.del(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK); }else{ System.out.println("沒有獲取到分布式鎖"); } }else{ System.out.println("沒有獲取到分布式鎖"); } } System.out.println("關閉訂單定時任務結束"); }