自定义注解,aop实现注解锁

简介: 自定义注解,aop实现注解锁

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

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

自定义注解

@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Lock {
    String description() default "";
}

定义切面类

public class LockAspect {
    private static Lock lock = new ReentrantLock(false);//互斥锁 参数默认false,不公平锁

    /**
     * 思考:为什么不用synchronized
     * service 默认是单例的,并发下lock只有一个实例
     */
    //Service层切点     用于记录错误日志
    @Pointcut("@annotation(com.example.thread.threaddemo.Lock)")
    public void lockAspect() {
    }

    @Around("lockAspect()")
    public Object around(ProceedingJoinPoint joinPoint) {
        lock.lock();
        Object obj = null;
        try {
            obj = joinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return obj;
    }
}


下图中箭头处改为自己的自定义注解类的全路径,就是包名加类名

 

准备测试,用售票的例子

@Service
public class Ticket1 implements Runnable {
    private int tickets = 100;

    @Override
    @Lock
    public void run() {
        while (tickets > 0) {
//            synchronized (Ticket.class) {
            if (tickets > 0) {
                tickets--;
                System.out.println(Thread.currentThread().getName() + "正在卖票,还剩下" + tickets + "张");
            }
//            }
            try {
                // 休眠一秒,让执行的效果更明显
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Ticket1 ticket = new Ticket1();
        Thread t1 = new Thread(ticket, "窗口一:");
        Thread t2 = new Thread(ticket, "窗口二:");
        Thread t3 = new Thread(ticket, "窗口三:");
        t1.start();
        t2.start();
        t3.start();
    }
}

synchronized锁的代码注释掉了,还需要在方法上加上自定义注解 @Lock

相关文章
|
1月前
|
XML Java 数据库
Spring5入门到实战------10、操作术语解释--Aspectj注解开发实例。AOP切面编程的实际应用
这篇文章是Spring5框架的实战教程,详细解释了AOP的关键术语,包括连接点、切入点、通知、切面,并展示了如何使用AspectJ注解来开发AOP实例,包括切入点表达式的编写、增强方法的配置、代理对象的创建和优先级设置,以及如何通过注解方式实现完全的AOP配置。
|
3月前
|
Java Spring 容器
基于注解的Aop开发,实现aop快速入门,基于注解的AOP开发
基于注解的Aop开发,实现aop快速入门,基于注解的AOP开发
|
2月前
|
分布式计算 Java MaxCompute
详解 Java 限流接口实现问题之在Spring框架中使用AOP来实现基于注解的限流问题如何解决
详解 Java 限流接口实现问题之在Spring框架中使用AOP来实现基于注解的限流问题如何解决
|
2月前
|
容器
springboot-自定义注解拦截ip aop和ioc
springboot-自定义注解拦截ip aop和ioc
|
3月前
|
XML Java 数据格式
Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))
Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))
34 0
|
3月前
|
Java Maven Spring
Spring中AOP最简单实例-@注解形式
Spring中AOP最简单实例-@注解形式
34 0
|
3月前
|
前端开发 Java 数据库
浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~
浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~
|
10天前
Micronaut AOP与代理机制:实现应用功能增强,无需侵入式编程的秘诀
【9月更文挑战第9天】AOP(面向切面编程)通过分离横切关注点提高模块化程度,如日志记录、事务管理等。Micronaut AOP基于动态代理机制,在应用启动时为带有特定注解的类生成代理对象,实现在运行时拦截方法调用并执行额外逻辑。通过简单示例展示了如何在不修改 `CalculatorService` 类的情况下记录 `add` 方法的参数和结果,仅需添加 `@Loggable` 注解即可。这不仅提高了代码的可维护性和可扩展性,还降低了引入新错误的风险。
32 13
|
1天前
Micronaut AOP与代理机制:实现应用功能增强,无需侵入式编程的秘诀
AOP(面向切面编程)能够帮助我们在不修改现有代码的前提下,为应用程序添加新的功能或行为。Micronaut框架中的AOP模块通过动态代理机制实现了这一目标。AOP将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,提高模块化程度。在Micronaut中,带有特定注解的类会在启动时生成代理对象,在运行时拦截方法调用并执行额外逻辑。例如,可以通过创建切面类并在目标类上添加注解来记录方法调用信息,从而在不侵入原有代码的情况下增强应用功能,提高代码的可维护性和可扩展性。
9 1
|
1月前
|
XML Java 数据格式
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
这篇文章是Spring5框架的AOP切面编程教程,通过XML配置方式,详细讲解了如何创建被增强类和增强类,如何在Spring配置文件中定义切入点和切面,以及如何将增强逻辑应用到具体方法上。文章通过具体的代码示例和测试结果,展示了使用XML配置实现AOP的过程,并强调了虽然注解开发更为便捷,但掌握XML配置也是非常重要的。
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解