多线程环境下,会出现线程不安全的问题,所以要对某些方法加锁以保证线程安全。常用的方法有:
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
已成功释放
网友评论