浣滆€咃細jingQ\鏉ユ簮锛歨ttps://www.sevenyuan.cn/涓€銆佷笟鍔¤儗鏅竴浜涗笟鍔¤姹傛槸姣旇緝鑰楁椂鐨勬搷浣滐紝闇€瑕佸姞閿佷互闃叉鍚庣画骞跺彂鎿嶄綔銆傚悓鏃跺鏁版嵁搴撲腑鐨勬暟鎹繘琛屾搷浣溿€傞渶瑕侀伩鍏嶅涔嬪墠鐨勪笟鍔¢€犳垚褰卞搷銆?銆佸垎鏋愯繃绋嬩娇鐢≧edis浣滀负鍒嗗竷寮忛攣锛屽皢閿佺殑鐘舵€佹斁鍦≧edis涓粺涓€缁存姢锛岃В鍐充簡闆嗙兢涓崟鏈篔VM涔嬮棿淇℃伅涓嶅吋瀹圭殑闂锛岃瀹氫簡鎿嶄綔椤哄簭锛屼繚鎶や簡姝g‘鎬х殑鐢ㄦ埛鏁版嵁銆傛⒊鐞嗚璁℃祦绋嬫柊寤烘敞瑙interface锛屽湪娉ㄨВ涓缃甶nput鏍囧織澧炲姞AOP鍒囩偣锛屾壂鎻忓叿浣撴敞瑙e缓绔婡Aspect鍒囬潰浠诲姟锛屾敞鍐宐ean骞舵嫤鎴叿浣撴柟娉曞弬鏁癙roceedingJoinPoint锛屽苟鍦ㄦ柟娉昿jp.proceed()鎴彇鍒囧叆鐐逛箣鍓嶅拰涔嬪悗杩涜閿佸畾锛屼换鍔℃墽琛屽畬鎴愬悗鍒犻櫎key銆傛牳蹇冩楠わ細鍔犻攣锛岃В閿侊紝缁х画鍔犻攣浣跨敤RedisTemplate鐨刼psForValue.setIfAbsent鏂规硶鍒ゆ柇鏄惁鏈塳ey锛岃缃竴涓殢鏈烘暟UUID.random().toString锛岀敓鎴愪竴涓殢鏈烘暟浣滀负value銆備粠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锛岃幏鍙栧繀瑕佺殑鍙傛暟閿佹搷浣滐紝缁х画鎿嶄綔缁撴潫涓氬姟锛岄噴鏀鹃攣銆?.鍦ㄥ疄闄呮搷浣滀箣鍓嶏紝AOP鐨勪娇鐢ㄦ柟娉曚篃宸茬粡鏁寸悊濂戒簡銆傚彲浠ュ弬鑰冪浉鍏冲睘鎬х被閰嶇疆涓氬姟灞炴€ф灇涓捐缃畃ublicenumRedisLockTypeEnum{/***鑷畾涔夐敭鍓嶇紑*/ONE("Business1","Test1"),TWO("Business2","Test2");绉佹湁瀛楃涓蹭唬鐮侊紱绉佹湁瀛楃涓叉弿杩帮紱RedisLockTypeEnum(Stringcode,Stringdesc){this.code=code;杩欎釜.desc=desc;}娴licStringgetCode(){杩斿洖浠g爜锛泒publicStringgetDesc(){杩斿洖鎻忚堪锛泒publicStringgetUniqueKey(Stringkey){杩斿洖瀛楃涓层€俧ormat("%s:%s",this.getCode(),key);}}浠诲姟闃熷垪淇濆瓨鍙傛暟publicclassRedisLockDefinitionHolder{/***涓氬姟鍞竴閿?/privateStringbusinessKey;/***閿佸畾鏃堕棿锛堢锛?/privateLonglockTime;/***鏈€鍚庢洿鏂版椂闂达紙姣锛?/privateLonglastModifyTime;/***淇濆瓨褰撳墠绾跨▼*/privateThreadcurrentTread;/***鎬诲皾璇曟鏁?/privateinttryCount;/***褰撳墠灏濊瘯娆℃暟*/privateintcurrentCount;/***鏇存柊鏃堕棿鍛ㄦ湡锛堟绉掞級锛屽叕寮?閿佸畾鏃堕棿锛堣浆涓烘绉掞級/3*/privateLongmodifyPeriod;publicRedisLockDefinitionHolder(StringbusinessKey,LonglockTime,LonglastModifyTime,ThreadcurrentTread,inttryCount){this.businessKey=businessKey;this.lockTime=閿佸畾鏃堕棿锛泃his.lastModifyTime=lastModifyTime;杩欎釜.currentTread=currentTread;this.tryCount=tryCount;this.modifyPeriod=lockTime*1000/3;}}璁剧疆鎷︽埅鐨勬敞瑙e悕绉癅Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD,ElementType.TYPE})public@interfaceRedisLockAnnotation{/***鍏蜂綋鍙傛暟鏍囪瘑锛岄粯璁や娇鐢ㄧ0涓笅鏍?/intlockFiled()榛樿涓?锛?***瓒呮椂閲嶈瘯娆℃暟*/inttryCount()default3;/***鐢变簬瀹氫箟浜嗛攣绫诲瀷*/RedisLockTypeEnumtypeEnum();/***閲婃斁鏃堕棿锛屼互绉掍负鍗曚綅*/longlockTime()default30;}鏍稿績鍒囬潰鎷︽埅鐨勬搷浣淩edisLockAspect.java杩欎釜绫诲垎涓轰笁閮ㄥ垎鏉ユ弿杩板叿浣撶殑鍔熻兘PointcutsettingDefined/***@annotation涓殑path琛ㄧず鎷︽埅鍏蜂綋鐨勬敞瑙?/@Pointcut("@annotation(cn.sevenyuan.demo.aop.lock.RedisLockAnnotation)")publicvoidredisLockPC(){}Aroundlock鍜屼笂涓€姝ラ噴鏀鹃攣瀹氫箟鎴戜滑瑕佹埅鍙栫殑鍒囩偣銆傛帴涓嬫潵灏辨槸鍦ㄥ垏鐐瑰墠鍚庡仛涓€浜涜嚜瀹氫箟鎿嶄綔锛欯Around(value="redisLockPC()")publicObjectaround(ProceedingJoinPointpjp)throwsThrowable{//瑙f瀽鍙傛暟Methodmethod=resolveMethod(pjp);RedisLockAnnotationannotation=method.getAnnotation(绾㈣壊isLockAnnotation.class);RedisLockTypeEnumtypeEnum=annotation.typeEnum();瀵硅薄[]鍙傛暟=pjp.getArgs();瀛楃涓瞮kString=params[annotation.lockFiled()].toString();//鐪佺暐璁稿鍙傛暟鏍¢獙鍜孍mptyStringbusinessKey=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();//灏嗚繖涓猅ask淇℃伅娣诲姞鍒扳€滃欢杩熲€濋槦鍒梙olderList.add(newRedisLockDefinitionHolder(businessKey,annotation.lockTime(),System.currentTimeMillis(),currentThread,annotation.tryCount()));//鎵ц涓氬姟鎿嶄綔result=pjp.proceed();//绾跨▼琚腑鏂紝鎶涘嚭寮傚父锛岃姹備腑鏂璱f(currentThread.isInterrupted()){thrownewInterruptedException("Youhadbeeninterrupted=-=");}}catch(InterruptedExceptione){log.error("涓柇寮傚父锛屽洖婊氫簨鍔?,e);thrownewException("涓柇寮傚父锛岃閲嶆柊鍙戦€佽姹?);}catch(Exceptione){log.error("鏈夐敊璇紝璇烽噸鏂版鏌?,e);}finally{//璇锋眰缁撴潫鍚庯紝鍒犻櫎key骞堕噴鏀鹃攣redisTemplate.delete(businessKey);log.info("閲婃斁閿侊紝businessKey涓篬"+businessKey+"]");}returnresult;}绠€鍗曟€荤粨涓€涓嬩笂闈㈢殑杩囩▼锛氳В鏋愭敞瑙e弬鏁帮紝鑾峰彇娉ㄨВ鍊煎拰鏂规硶涓婄殑鍙傛暟鍊硷紝redis鍔犻攣骞惰缃秴鏃舵椂闂达紝灏嗚繖涓猅ask淇℃伅娣诲姞鍒扳€渄elay鈥濋槦鍒楋紝浠ュ強continue鐨勬椂鍊欙紝閫氳繃鎻愬墠閲婃斁閿侊紝娣诲姞涓€涓嚎绋嬩腑鏂爣蹇楁潵缁撴潫璇锋眰锛屽湪finally閲婃斁閿佺户缁繍琛屻€傝繖閲屼娇鐢⊿cheduledExecutorService缁存姢涓€涓嚎绋嬶紝涓嶆柇鍒ゆ柇浠诲姟闃熷垪涓殑浠诲姟骞跺欢闀胯秴鏃舵椂闂达細//鎵弿浠诲姟闃熷垪privatestaticConcurrentLinkedQueue
