1銆備笟鍔¤儗鏅竴浜涗笟鍔¤姹傛槸姣旇緝鑰楁椂鐨勬搷浣滐紝闇€瑕佸姞閿佷互闃叉鍚庣画鐨勫苟鍙戞搷浣溿€傚悓鏃讹紝瀵规暟鎹簱鏁版嵁鐨勬搷浣滈渶瑕侀伩鍏嶅奖鍝嶄箣鍓嶇殑涓氬姟銆?銆佸垎鏋愯繃绋嬩娇鐢≧edis浣滀负鍒嗗竷寮忛攣锛屽皢閿佺殑鐘舵€佹斁鍦≧edis涓粺涓€缁存姢锛岃В鍐充簡闆嗙兢涓崟鏈篔VM涔嬮棿淇℃伅涓嶅吋瀹圭殑闂锛岃瀹氫簡鎿嶄綔椤哄簭锛屼繚鎶や簡姝g‘鎬х殑鐢ㄦ埛鏁版嵁銆傛⒊鐞嗚璁℃祦绋嬫柊寤烘敞瑙interface锛屽湪娉ㄨВ涓缃甶nput鏍囧織澧炲姞AOP鍒囩偣锛屾壂鎻忓叿浣撴敞瑙e缓绔婡Aspect鍒囬潰浠诲姟锛屾敞鍐宐ean骞舵嫤鎴叿浣撴柟娉曞弬鏁癙roceedingJoinPoint锛屽苟鍦ㄦ柟娉昿jp.proceed()鎴彇鍒囧叆鐐逛箣鍓嶅拰涔嬪悗杩涜閿佸畾锛屼换鍔℃墽琛屽畬鎴愬悗鍒犻櫎key銆傛牳蹇冩楠わ細鍔犻攣銆佽В閿併€佸欢缁€備娇鐢≧edisTemplate鐨刼psForValue.setIfAbsent鏂规硶鍒ゆ柇鏄惁鏈塳ey锛岃缃竴涓殢鏈烘暟UUID.random()銆倀oString锛岀敓鎴愪竴涓殢鏈烘暟浣滀负鍊笺€備粠redis鑾峰彇閿佸悗锛岀粰key璁剧疆expire杩囨湡鏃堕棿锛岃繃鏈熷悗鑷姩閲婃斁閿併€傛寜鐓ц繖绉嶈璁★紝鍙湁绗竴涓姹傛垚鍔熻缃甂ey鎵嶈兘杩涜鍚庣画鐨勬暟鎹搷浣滐紝鍚庣画鐨勮姹傞兘浼氬洜涓烘棤娉曡幏鍙栶煍愯祫婧愯€屽け璐ャ€傝秴鏃堕棶棰樻媴蹇僷jp.proceed()鍒囩偣鎵ц鏂瑰紡杩囦簬鑰楁椂锛屽鑷碦edis涓殑key鍥犺秴鏃舵彁鍓嶉噴鏀俱€傛瘮濡傜嚎绋婣鍏堣幏鍙栭攣锛宲roceed鏂规硶鑰楁椂锛岃秴杩囬攣瓒呮椂鏃堕棿锛岃秴鏃堕噴鏀鹃攣銆傛鏃跺彟涓€涓嚎绋婤鎴愬姛鑾峰彇鍒癛edis閿侊紝涓や釜绾跨▼鍚屾椂鎿嶄綔鍚屼竴鎵规暟鎹紝瀵艰嚧鏁版嵁涓嶄竴鑷淬€傜簿纭殑銆傝В鍐虫柟娉曪細娣诲姞涓€涓湭瀹屾垚涓旀湭閲婃斁閿佺殑鈥滅画琛屸€濅换鍔★細缁存姢涓€涓畾鏃剁嚎绋嬫睜ScheduledExecutorService锛屾瘡2s鎵弿涓€娆″姞鍏ラ槦鍒楃殑Tasks锛屽垽鏂槸鍚︿复杩戣繃鏈熸椂闂淬€傚叕寮忎负锛歔杩囨湡鏃堕棿]<=[褰撳墠鏃堕棿]+[澶辫触闂撮殧锛堜笁鍒嗕箣涓€瓒呮椂锛塢/***绾跨▼姹狅紝姣忎釜JVM浣跨敤涓€涓嚎绋嬬淮鎶eyAliveTime锛屽畾鏃舵墽琛宺unnable*/privatestaticfinalScheduledExecutorServiceSCHEDULER=newScheduledThreadPoolExecutor(1,newBasicThreadFactory.Builder().namingPattern("redisLock-schedule-pool").daemon(true).build());static{SCHEDULER.scheduleAtFixedRate(()->{//dosomethingtoextendtime},0,2,TimeUnit.SECONDS);}3.璁捐鏂规缁忚繃浠ヤ笂鍒嗘瀽锛屽悓浜嬪皬馃悷璁捐浜嗚繖涓柟妗堬細鏁翠綋娴佺▼鍓嶉潰宸茬粡璁茶繃锛岃繖閲屾湁鍑犱釜鏍稿績姝ラ锛氭嫤鎴敞瑙RedisLock锛岃幏鍙栧繀瑕佺殑鍙傛暟閿佹搷浣滐紝缁х画鎿嶄綔缁撴潫涓氬姟锛岄噴鏀鹃攣*4銆傚湪瀹為檯鎿嶄綔涔嬪墠锛孉OP鐨勪娇鐢ㄦ柟娉曚篃宸茬粡鏁寸悊鍑烘潵浜嗭紝澶у鍙互鍙傝€冧竴涓嬨€傜浉鍏冲睘鎬х被閰嶇疆涓氬姟灞炴€ф灇涓捐缃甡publicenumRedisLockTypeEnum{/***鑷畾涔夐敭鍓嶇紑*/ONE("Business1","Test1"),TWO("Business2","Test2");绉佹湁瀛楃涓蹭唬鐮侊紱绉佹湁瀛楃涓叉弿杩帮紱RedisLockTypeEnum(Stringcode,Stringdesc){this.code=code;this.desc=desc;}publicStringgetCode(){杩斿洖浠g爜锛泒publicStringgetDesc(){杩斿洖鎻忚堪锛泒publicStringgetUniqueKey锛堝瓧绗︿覆閿級{returnString.format("%s:%s",this.getCode(),key);}}`浠诲姟闃熷垪瀛樺偍鍙傛暟`publicclassRedisLockDefinitionHolder{/***涓氬姟鍞竴閿?/privateStringbusinessKey;/****閿佸畾鏃堕棿锛堢锛?/privateLonglockTime;/****鏈€鍚庢洿鏂版椂闂达紙姣锛?/privateLonglastModifyTime;/***淇濆瓨褰撳墠绾跨▼*/rrent/privateTread;****鎬诲皾璇曟鏁?/privateinttryCount;/***褰撳墠灏濊瘯娆℃暟*/privateintcurrentCount;/***鏇存柊鏃堕棿鍛ㄦ湡锛堟绉掞級锛屽叕寮?閿佸畾鏃堕棿锛堣浆涓烘绉掞級/3*/privateLongmodifyPeriod;publicRedisLockDefinitionHolder(StringbusinessKey,LonglockTime,LonglastModifyTime,ThreadcurrentTread,inttryCount){this.inessKey=businessKey;this.lockTime=閿佸畾鏃堕棿锛泃his.lastModifyTime=lastModifyTime;this.currentTread=currentTread;this.tryCount=tryCount;(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD,ElementType.TYPE})public@interfaceRedisLockAnnotation{/***鍏蜂綋鍙傛暟鏍囪瘑锛岄粯璁ゅ彇绗?涓笅鏍?/intlockFiled()default0;/***瓒呮椂閲嶈瘯*/inttryCount()default3;/***鑷畾涔夐攣绫诲瀷*/RedisLockTypeEnumtypeEnum();/***閲婃斁鏃堕棿锛屼互绉掍负鍗曚綅*/longlockTime()default30;}`鏍稿績鍒囬潰鎷︽埅鐨勬搷浣淩edisLockAspect.java杩欎釜绫诲垎涓轰笁閮ㄥ垎鏉ユ弿杩板叿浣撶殑鍔熻兘Pointcut璁剧疆/***璺緞@annotation涓〃绀烘嫤鎴叿浣撴敞瑙?/@Pointcut("@annotation(cn.sevenyuan.demo.aop.lock.RedisLockAnnotation)")publicvoidredisLockPC(){}鍓嶅悗宸﹀彸鍔犻攣鍜岄噴鏀鹃攣鍓嶉潰鍑犳瀹氫箟浜嗘垜浠鎴彇鐨勫垏鐐癸紝涓嬩竴姝ュ氨鏄湪鍓嶅悗鍋氫竴浜涜嚜瀹氫箟鍒囩偣鍚庢搷浣滐細@Around(value="redisLockPC()")publicObjectaround(ProceedingJoinPointpjp)throwsThrowable{//瑙f瀽鍙傛暟Methodmethod=resolveMethod(pjp);RedisLockAnnotationannotation=method.getAnnotation(RedisLockAnnotation.class);RedisLockTypeEnumtypeEnum=annotation.typeEnum();Object[]params=pjp.getArgs();StringukString=params[annotation.lockFiled()].toString();//鐪佺暐寰堝鍙傛暟锛屾鏌ュ垽鏂┖StringbusinessKey=typeEnum.getUniqueKey(ukString);StringuniqueValue=UUID.randomUUID().toString();//閿佸畾瀵硅薄result=null;try{booleanisSuccess=redisTemplate.opsForValue().setIfAbsent(businessKey,uniqueValue);if(!isSuccess){thrownewException("浣犱笉鑳借繖鏍峰仛锛屽洜涓哄彟涓€涓汉宸茬粡鑾峰緱浜嗛攣=-=");}redisTemplate.expire(businessKey,annotation.lockTime(),TimeUnit.SECONDS);绾跨▼currentThread=Thread.currentThread();//灏嗘Task淇℃伅娣诲姞鍒扳€滃欢杩熲€濋槦鍒梙olderList.add(newRedisLockDefinitionHolder(businessKey,annotation.lockTime(),System.currentTimeMillis(),currentThread,annotation.tryCount()));//鎵ц涓氬姟鎿嶄綔result=pjp.proceed();//绾跨▼琚腑鏂紝鎶涘嚭寮傚父锛岃姹備腑鏂璱f(currentThread.isInterrupted()){thrownewInterruptedException("Youhadbeeninterrupted=-=");}}catch(InterruptedExceptione){鏃ュ織銆俥rror("涓柇寮傚父锛屽洖婊氫簨鍔?,e);thrownewException("涓柇寮傚父锛岃閲嶆柊鍙戦€佽姹?);}catch(Exceptione){log.error("鏈夐敊璇紝璇烽噸鏂版鏌?,e);}finally{//璇锋眰缁撴潫鍚庯紝鍒犻櫎key骞堕噴鏀鹃攣redisTemplate.delete(businessKey);log.info("閲婃斁閿侊紝businessKey涓篬"+businessKey+"]");}returnresult;}浠ヤ笂杩囩▼绠€鍗曟€荤粨锛氳В鏋愭敞瑙e弬鏁帮紝鑾峰彇娉ㄨВ鍊煎拰鏂规硶涓婄殑鍙傛暟鍊硷紝閿佸畾redis骞惰缃秴鏃舵椂闂村皢Task淇℃伅娣诲姞鍒扳€渄elay鈥濋槦鍒椾腑continuation锛岃鏂规硶鎻愬墠閲婃斁閿佸苟娣诲姞涓€涓嚎绋嬩腑鏂爣蹇楁潵缁撴潫璇锋眰锛屾渶鍚庡湪continuation鎿嶄綔杩囩▼涓噴鏀鹃攣杩欓噷浣跨敤ScheduledExecutorService鏉ョ淮鎶や竴涓嚎绋嬫潵涓嶆柇鍒ゆ柇浠诲姟[闃熷垪涓殑浠诲姟鍜屽欢闀胯秴鏃舵椂闂碷:`//鎵弿浠诲姟闃熷垪privatestaticConcurrentLinkedQueue
