Home  >  Article  >  How to make singleton bean thread safe and have better performance in java?

How to make singleton bean thread safe and have better performance in java?

王林
王林forward
2024-02-09 09:00:20983browse

In Java development, the singleton pattern is a commonly used design pattern to ensure that a class has only one instance object. However, in a multi-threaded environment, using the singleton pattern may cause thread safety issues, thus affecting the performance and correctness of the program. So, how to make singleton bean thread safe and have better performance in Java? PHP editor Yuzai will introduce and answer the following aspects for you.

Question content

I am trying to test the code below with multiple users. But since the class is a singleton managed by spring, there is only one created object and multiple threads are trying to access the same object.

Due to inconsistent output strings. Try to solve this problem by using synchronized keyword in applogger method. It's working as expected. But we need to compromise on performance.

How to handle singleton beans in a multi-threaded environment and obtain better performance through instance variable (stringbuilder) modification?

Edit the code and add the aggregatelogger method. This method will aggregate the string to an existing stringbuilder that has been declared at the class level, so that the stringbuilder will have aggregated logs from the applogger and aggregatelogger methods.

@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;
    }
    
}

Solution

Your design is wrong, please forgive me for being so blunt. Even within one business transaction that you want to log, there may be multiple application layers performing multiple operations in multiple threads. Why does all of this have to be in one log message? Typically you log all messages using some kind of customer and/or transaction ID or whatever correctly identifies the logical entity you want to track and log. Most logging frameworks use some sort of Mapped Diagnostic Context (MDC)that. Whether you log into the console or a database or log aggregator such as Logstash or Graylog, you can search, filter, and aggregate by the entity or transaction you're interested in to find all corresponding log messages. No need to put them all into one log message.

Of course, instead of polluting your core code with log statements, you can leverage aspects for logging. Breaking out cross-cutting concerns like logging is one of the main advantages of AOP. But you should do it right. So your singleton aspect either uses MDC or does its own bookkeeping in some kind of mapping. I recommend using the tools your logging framework already provides and letting the aspect focus on what it does best, which is intercepting the correct join points.

Since performance is also one of your concerns, you may want to configure your logging framework to log asynchronously to make your application faster and more responsive. Logging to a file is also generally faster than logging to the console. Maybe this GitHub repository has interesting information for you with its interesting readme and JMH benchmarks in addition to what we discuss here. If you happen to speak German, I posted a few days ago on this Heise.de blog. The German content of this article is essentially the same as the English readme, I just wanted to provide my sources.

Regardless, when using asynchronous logging, the log aggregation ID becomes more important in a multi-threaded context.

The above is the detailed content of How to make singleton bean thread safe and have better performance in java?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete