通过自定义注解对方法加锁

多线程环境下,会出现线程不安全的问题,所以要对某些方法加锁以保证线程安全。常用的方法有:

final Reentrantlock lock = new Reentrantlock();
public void func(){
  lock.tryLock();
  //TODO
  lock.unlock();
}

但是如果方法过多,每个方法前后都加这么一句,有点麻烦了,而且代码可读性也会差一些。可以使用aop切面编程,对某些加有特定注解(自定义注解)的方法做加锁操作即可。

定义注解

@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface TryLock(){
  //TODO
}

定义切面类

public class TryLockAop{
  final ReentrantLock lock = new ReentrantLock();
  
  public Object trylockByAop(ProceedingJoinPoint joinPoint){
    Object obj = null;
    try{
      if(!lock.tryLock()){
        throw new IllegalArgumentException("当前资源证被占用");
     }
      System.out.println("已成功加锁");
      obj = joinPoint.proceed();
    }catch(Throwable){
      //TODO
    }finally{
      if(lock.isLocked()){
        lock.unlock();
        System.out.println("已成功释放");
      }
    }
    return obj;
  }
}

定义使用类

public class HelloWorld{
  //使用自定义注解@TryLock
  @TryLock
  public void hello(){
    System.out.println("hello world");
  }
}

配置文件

<bean id="helloWorld" class="com.xxx.HelloWorld"/>

<bean id="TryLockAop" class="com.xxx.TryLockAop"/>

<aop:config>
  <aop:aspect>
    <!-- 对加有注解@TryLock的方法执行该切面的方法 -->
    <aop:pointcut id="testTrylockPoint" expression="@annotation(com.xxx.TryLock)" />
    <aop:around method="trylockByAop" pointcut-ref="testTrylockPoint"/>
  </aop:aspect>
</aop:config>

测试

public static void main(String[] args){
  ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
  context.start();
  HelloWorld hello = (HelloWorld)context.getBean("HelloWorld");
  hello.hello();
}

结果为:

已成功加锁
hello
已成功释放
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容