<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
package com.example.demo.annotation; import java.lang.annotation.*; /** * desc: 自定義 redisson 分散式鎖註解 * * @author: 邢陽 * @mail: xydeveloper@126.com * @create 2021-05-28 16:50 */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface Lock { /** * 鎖的key spel 表示式 * * @return */ String key(); /** * 持鎖時間 * * @return */ long keepMills() default 20; /** * 沒有獲取到鎖時,等待時間 * * @return */ long maxSleepMills() default 30; }
package com.example.demo.utils; import com.example.demo.annotation.Lock; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.expression.EvaluationContext; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.stereotype.Component; import java.util.Objects; import java.util.concurrent.TimeUnit; /** * desc: 解析 自定義 redisson 分散式鎖註解 * * @author: 邢陽 * @mail: xydeveloper@126.com * @create 2021-05-28 16:50 */ @Aspect @Component public class LockAspect { @Autowired private RedissonClient redissonClient; /** * 用於SpEL表示式解析. */ private final SpelExpressionParser spelExpressionParser = new SpelExpressionParser(); /** * 用於獲取方法引數定義名字. */ private final DefaultParameterNameDiscoverer defaultParameterNameDiscoverer = new DefaultParameterNameDiscoverer(); @Around("@annotation(com.example.demo.annotation.Lock)") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { Object object = null; RLock lock = null; try { // 獲取註解實體資訊 Lock lockEntity = (((MethodSignature) proceedingJoinPoint.getSignature()).getMethod()) .getAnnotation(Lock.class); // 根據名字獲取鎖範例 lock = redissonClient.getLock(getKeyBySpeL(lockEntity.key(), proceedingJoinPoint)); if (Objects.nonNull(lock)) { if (lock.tryLock(lockEntity.maxSleepMills(), lockEntity.keepMills(), TimeUnit.SECONDS)) { object = proceedingJoinPoint.proceed(); } else { throw new RuntimeException(); } } } finally { if (Objects.nonNull(lock) && lock.isHeldByCurrentThread()) { lock.unlock(); } } return object; } /** * 獲取快取的key * * key 定義在註解上,支援SPEL表示式 * * @return */ public String getKeyBySpeL(String spel, ProceedingJoinPoint proceedingJoinPoint) { MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature(); String[] paramNames = defaultParameterNameDiscoverer.getParameterNames(methodSignature.getMethod()); EvaluationContext context = new StandardEvaluationContext(); Object[] args = proceedingJoinPoint.getArgs(); for (int i = 0; i < args.length; i++) { context.setVariable(paramNames[i], args[i]); } return String.valueOf(spelExpressionParser.parseExpression(spel).getValue(context)); } }
/** * desc: 鎖 * * @author: 邢陽 * @mail: xydeveloper@126.com * @create 2021-05-28 17:58 */ @Service public class LockService { @Lock(key = "#user.id", keepMills = 10, maxSleepMills = 15) public String lock(User user) { System.out.println("持鎖"); return ""; } }
分散式架構一定會用到分散式鎖。目前公司使用的基於redis的redisson分散式鎖。
1.訂單修改操作,首先要獲取該訂單的分散式鎖,能取到才能去操作。lockey可以是訂單的主鍵id。
2.庫存操作,也要按照客戶+倉庫+sku維護鎖定該庫存,進行操作。
程式碼:
public class RedissonManager { private static RedissonClient redisson; static { Config config = new Config(); config.useSentinelServers() .addSentinelAddress("redis://127.0.0.1:26379","redis://127.0.0.1:7301", "redis://127.0.0.1:7302") .setMasterName("mymaster") .setReadMode(ReadMode.SLAVE) .setTimeout(10000).setDatabase(0).setPassword("123***"); redisson = Redisson.create(config); } /** * 獲取Redisson的範例物件 * @return */ public static RedissonClient getRedisson(){ return redisson;} }
import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import java.util.concurrent.TimeUnit; public class DistributedLock { private static RedissonClient redissonClient = RedissonManager.getRedisson(); public static boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) { RLock lock = redissonClient.getLock(lockKey); try { return lock.tryLock(waitTime, leaseTime, unit); } catch (InterruptedException e) { return false; } } public static void unlock(String lockKey) { RLock lock = redissonClient.getLock(lockKey); lock.unlock(); } }
public class RedissonTest { public static void main(String[] args) throws Exception{ Thread.sleep(2000L); for (int i = 0; i < 3; i++) { new Thread(() -> { try { //tryLock,第三個引數是等待時間,5秒內獲取不到鎖,則直接返回。 第四個引數 30是30秒後強制釋放 boolean hasLock = DistributedLock.tryLock("lockKey", TimeUnit.SECONDS,5,30); //獲得分散式鎖 if(hasLock){ System.out.println("idea1: " + Thread.currentThread().getName() + "獲得了鎖"); /** * 由於在DistributedLock.tryLock設定的等待時間是5s, * 所以這裡如果休眠的小於5秒,這第二個執行緒能獲取到鎖, * 如果設定的大於5秒,則剩下的執行緒都不能獲取鎖。可以分別試試2s,和8s的情況 */ Thread.sleep(10000L); DistributedLock.unlock("lockKey"); } else { System.out.println("idea1: " + Thread.currentThread().getName() + "無法獲取鎖"); } } catch (Exception e) { e.printStackTrace(); } }) .start(); } } }
我們再開啟一個idea,可以把程式碼複製一份。同事啟動兩個RedissonTest ,模擬了並行操作。
測試結果:
idea2: Thread-1獲得了鎖
idea2: Thread-0無法獲取鎖
idea2: Thread-2無法獲取鎖
idea1: Thread-2無法獲取鎖
idea1: Thread-0無法獲取鎖
idea1: Thread-1無法獲取鎖
從測試結果發現,最後是隻能有一個idea的一個執行緒能獲取到鎖。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45