爲何須要有分佈式鎖呢,在單點的時候synchronized 就能解決,可是服務拆分以後,每一個服務都是單獨的機器,沒法解決,因此出現了分佈式鎖,其實也就是用各類手段,實現獲取惟一鎖,別人沒法獲得。html
其實在作分佈式鎖的前提,須要先明白,synchronized 爲啥不能使用了,啥原理讓他在一個機器上能夠使用。java
衆所周知 Synchronize
關鍵字是解決併發問題經常使用解決方案,有如下三種使用方式:redis
Class
對象。{}
中的對象。 實現原理:
JVM
是經過進入、退出對象監視器( Monitor
)來實現對方法、同步塊的同步的。併發
具體實現是在編譯以後在同步方法調用前加入一個 monitor.enter
指令,在退出方法和異常處插入 monitor.exit
的指令。分佈式
其本質就是對一個對象監視器( Monitor
)進行獲取,而這個獲取過程具備排他性從而達到了同一時刻只能一個線程訪問的目的。spa
而對於沒有獲取到鎖的線程將會阻塞到方法入口處,直到獲取鎖的線程 monitor.exit
以後才能嘗試繼續獲取鎖。線程
能夠經過使用 javap -c Synchronize
能夠查看編譯以後的具體信息 ,這裏我就再也不粘貼了。code
因此能夠知道,單獨的Java虛擬機是可實現鎖的,可是多臺手就伸不到了,只能在依賴外部的形式去產生一個惟一鎖。htm
以上是參考別人的博客拿到的信息,親自試用獲得,準確 :連接:https://www.jianshu.com/p/2ba154f275ea對象
主要是利用了redis的set NX的原理,以及對redis的script腳本原子性利用。(我的見解,其實後面一步就看各自的程序邏輯如何去斷定到底要不要這一步了)
簡單的說一下主要流程:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Documented public @interface DistributedLock { /** * 自定義形式添加你對分佈式鎖的對外配置屬性 * 例如:key的規則,鎖的超時時間,獲取鎖的等待時間,等一系列的屬性配置 * */ }
@Aspect @Component public class DistributedLockAspect { /** * 層切點 */ @Pointcut("@annotation(com.creditease.hardess.common.annotation.DistributedLock)") public void distributedLockAspect() {} /** * @param joinPoint 切點 * @return Object 添加分佈式鎖後,實際調用業務邏輯部分代碼的返回值 * @throws Throwable 產生的全部異常,爲了不對異常處理流程產生干擾,全部異常都應該繼續拋出 */ @Around("distributedLockAspect()") public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { /** *主要寫一些鎖的獲取,和業務邏輯執行,鎖的刪除等 * */ return returnObject; } /** * 獲取 DistributedLock 註解 * * @param joinPoint * @return 代碼中定義的註解 * @throws NoSuchMethodException */ private static DistributedLock getDistributedLock(ProceedingJoinPoint joinPoint) throws NoSuchMethodException { String methodName = joinPoint.getSignature().getName(); Class<?> classTarget = joinPoint.getTarget().getClass(); Class<?>[] par = ((MethodSignature) joinPoint.getSignature()).getParameterTypes(); Method objMethod = classTarget.getMethod(methodName, par); return objMethod.getAnnotation(DistributedLock.class); } } }