首页  >  文章  >  如何在java中使单例bean线程安全并具有更好的性能?

如何在java中使单例bean线程安全并具有更好的性能?

王林
王林转载
2024-02-09 09:00:20983浏览

在Java开发中,单例模式是一种常用的设计模式,用于确保一个类只有一个实例对象。然而,在多线程环境下,使用单例模式可能会引发线程安全问题,从而影响程序的性能和正确性。那么,如何在Java中使单例bean线程安全并具有更好的性能?php小编鱼仔将在以下几个方面为大家进行介绍和解答。

问题内容

我正在尝试与多个用户测试下面的代码。但由于该类是由 spring 管理的单例,因此只有一个已创建的对象,并且多个线程试图访问同一个对象。

由于输出字符串不一致。尝试通过在 applogger 方法中使用 synchronized 关键字来解决此问题。它正在按预期工作。但我们需要在性能上做出妥协。

如何在多线程环境中处理单例bean,并通过实例变量(stringbuilder)修改来获得更好的性能?

编辑代码,添加aggregatelogger方法。此方法会将字符串聚合到已在类级别声明的现有 stringbuilder,以便 stringbuilder 将具有来自 applogger 和aggregatelogger 方法的聚合日志。

@Aspect
    @Slf4j
    @Component
    public class A{
     private StringBuilder builder = new StringBuilder();
     public StringBuilder getSb(){
     return builder;
     }
     public void appendToSb(String s){
     builder.append(s);
     }

    @Around("@annotation(execTimeLogger)")
    public Object appLogger(ProceedingJointPoint pjp){
     long startTime = xxx;
     Object object = pjp.proceed();
     long endTime = xxx;
     String str = "Hello";
     appendToSb(str);
    return object;
    }

    @Around("@annotation(logger)")
    public Object aggregateLogger(ProceedingJointPoint pjp){
     long startTime = xxx;
     Object object = pjp.proceed();
     long endTime = xxx;
     String str = "World";
     appendToSb(str);
     log.info(getSb().toString()); // o/p will be Aggregated Log 
     getSb().setLength(0);
    return object;
    }
    
}

解决方法

你的设计是错误的,请原谅我这么直率。即使在您想要记录的一项业务事务中,也可能有多个应用程序层在多个线程中执行多项操作。为什么所有这些都必须在一条日志消息中?通常,您使用某种客户和/或事务 ID 或任何正确标识您想要跟踪和记录的逻辑实体的内容来记录所有消息。大多数日志记录框架使用某种映射诊断上下文 (MDC)那。无论您登录到控制台还是数据库或日志聚合器(如 Logstash 或 Graylog),您都可以按您感兴趣的实体或事务进行搜索、过滤和聚合,找到所有相应的日志消息。无需将它们全部放入一条日志消息中。

当然,您可以利用方面来进行日志记录,而不是用日志语句污染您的核心代码。分解出像日志记录这样的横切关注点是 AOP 的主要优点之一。但你应该做对。因此,您的单例方面要么使用 MDC,要么在某种映射中进行自己的簿记。我建议使用您的日志框架已经提供的工具,并让方面专注于它最擅长的事情,即拦截正确的连接点。

由于性能也是您关心的问题之一,因此您可能希望将日志框架配置为异步日志,从而使您的应用程序更快、响应更快。通常,记录到文件也比记录到控制台更快。也许这个 GitHub 存储库除了我们在这里讨论的内容之外,其有趣的自述文件和 JMH 基准测试还为您提供了有趣的信息。如果您碰巧会说德语,几天前在 此 Heise.de 博客。这篇文章的德语内容基本上与英语自述内容相同,我只是想提供我的来源。

无论如何,当使用异步日志记录时,日志聚合 ID 在多线程上下文中变得更加重要。

以上是如何在java中使单例bean线程安全并具有更好的性能?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文转载于:stackoverflow.com。如有侵权,请联系admin@php.cn删除