Maison >Java >Comment sécuriser les threads du bean singleton et obtenir de meilleures performances en Java ?

Comment sécuriser les threads du bean singleton et obtenir de meilleures performances en Java ?

王林
王林avant
2024-02-09 09:00:201050parcourir

Dans le développement Java, le modèle singleton est un modèle de conception couramment utilisé pour garantir qu'une classe n'a qu'un seul objet d'instance. Cependant, dans un environnement multithread, l'utilisation du modèle singleton peut entraîner des problèmes de sécurité des threads, affectant ainsi les performances et l'exactitude du programme. Alors, comment sécuriser les threads du bean singleton et obtenir de meilleures performances en Java ? L'éditeur PHP Yuzai présentera et répondra aux aspects suivants pour vous.

Contenu de la question

J'essaie de tester le code ci-dessous avec plusieurs utilisateurs. Mais comme la classe est un singleton géré par Spring, il n'y a qu'un seul objet créé et plusieurs threads tentent d'accéder au même objet.

En raison de chaînes de sortie incohérentes. Essayez de résoudre ce problème en utilisant le mot-clé synchronisé dans la méthode applogger. Cela fonctionne comme prévu. Mais nous devons faire des compromis sur les performances.

Comment gérer les beans singleton dans un environnement multithread et obtenir de meilleures performances grâce à la modification de variables d'instance (stringbuilder) ?

Modifiezcodez et ajoutez la méthode AggregateLogger. Cette méthode agrègera la chaîne dans un constructeur de chaînes existant qui a été déclaré au niveau de la classe, de sorte que le constructeur de chaînes disposera des journaux agrégés des méthodes applogger et 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;
    }
    
}

Solution

Votre conception est fausse, s'il vous plaît, pardonnez-moi d'être si direct. Même au sein d’une transaction commerciale que vous souhaitez enregistrer, plusieurs couches d’application peuvent effectuer plusieurs opérations dans plusieurs threads. Pourquoi tout cela doit-il être dans un seul message de journal ? En règle générale, vous enregistrez tous les messages en utilisant une sorte d'ID client et/ou de transaction ou tout ce qui identifie correctement l'entité logique que vous souhaitez suivre et enregistrer. La plupart des frameworks de journalisation utilisent une sorte de Mapped Diagnostic Context (MDC)qui. Que vous vous connectiez à la console, à une base de données ou à un agrégateur de journaux tel que Logstash ou Graylog, vous pouvez rechercher, filtrer et agréger par entité ou transaction qui vous intéresse pour trouver tous les messages de journal correspondants. Pas besoin de les mettre tous dans un seul message de journal.

Bien sûr, au lieu de polluer votre code principal avec des instructions de journalisation, vous pouvez exploiter les aspects de la journalisation. La résolution de problèmes transversaux comme l’exploitation forestière est l’un des principaux avantages de l’AOP. Mais tu devrais le faire correctement. Ainsi, votre aspect singleton utilise MDC ou effectue sa propre comptabilité dans une sorte de cartographie. Je recommande d'utiliser les outils que votre framework de journalisation fournit déjà et de laisser l'aspect se concentrer sur ce qu'il fait le mieux, c'est-à-dire intercepter les bons points de jointure.

Étant donné que les performances sont également l'une de vos préoccupations, vous souhaiterez peut-être configurer votre infrastructure de journalisation pour la journalisation asynchrone afin de rendre votre application plus rapide et plus réactive. La journalisation dans un fichier est également généralement plus rapide que la connexion à la console. Peut-être que ce Référentiel GitHub avec son fichier readme intéressant et ses benchmarks JMH vous fournit des informations intéressantes en plus de ce dont nous discutons ici. Si vous parlez allemand, il y a quelques jours sur ce blog Heise.de. Le contenu allemand de cet article est essentiellement le même que le readme anglais, je voulais juste fournir mes sources.

Quoi qu'il en soit, lors de l'utilisation de la journalisation asynchrone, l'ID d'agrégation de journaux devient plus important dans un contexte multithread.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer