某些场景下,有可能一个方法不能被并发执行,有可能一个方法的特定参数不能被并发执行。比如不能将一个消息发送多次,创建缓存最好只创建一次等等。为了实现上面的目标我们就需要采用同步机制来完成,但同步的逻辑如何实现呢,是否会影响到原有逻辑呢?
这里讲的嵌入式是说获取锁以及释放锁的逻辑与业务代码耦合在一起,又分分布式与单机两种不同场景的不同实现。
下面方法,每个productId不允许并发访问,所以这里可以直接用synchronized来锁定不同的参数。
System.out.print("productId:" productId "time:" newDate());
测试脚本:三个相同的参数
0,两个不同的参数1和
2,通过一个多线程的例子来模似。如果有并发请求的测试工具可能效果会更好。
ExecutorServiceexecutorService=Executors.newFixedThreadPool
(5);
RLocklock=this.redissonService.getRedisson().getLock(productId.toString());
booleanlocked=lock.tryLock(3000,500,TimeUnit.MILLISECONDS);
能否将锁的逻辑隐藏起来,通过在特定方法上增加注解来实现呢?就像SpringCache的应用。当然是可以的,这里我们只需要解决如下三个问题:
key,锁对象的标识,就是上面提到的方法的某些参数。一般由方法所属类的完全限定名,方法名以及指定的参数构成。
expirationTime,锁的生命周期,可以有效避免因特殊原因未释放锁导致其它线程永远获取不到锁的局面。
TimeUnittimeUnit()defaultTimeUnit.MILLISECONDS;
由于我们的目标是注解式锁,这里通过AOP的方式来实现,具体依赖AspectJ,创建一个拦截器:
publicabstractclassAbstractRequestLockInterceptor{
protectedabstractbooleantryLock(longwaitTime,longleaseTime,TimeUnitunit,Locklock)throwsInterruptedException;