Heim  >  Artikel  >  Wie kann man einen Singleton-Bean-Thread sicher machen und eine bessere Leistung in Java erzielen?

Wie kann man einen Singleton-Bean-Thread sicher machen und eine bessere Leistung in Java erzielen?

王林
王林nach vorne
2024-02-09 09:00:20983Durchsuche

In der Java-Entwicklung ist das Singleton-Muster ein häufig verwendetes Entwurfsmuster, um sicherzustellen, dass eine Klasse nur ein Instanzobjekt hat. In einer Umgebung mit mehreren Threads kann die Verwendung des Singleton-Musters jedoch zu Thread-Sicherheitsproblemen führen und somit die Leistung und Korrektheit des Programms beeinträchtigen. Wie kann man also Singleton-Bean-Threads sicher machen und eine bessere Leistung in Java erzielen? Der PHP-Editor Yuzai wird die folgenden Aspekte für Sie vorstellen und beantworten.

Frageninhalt

Ich versuche, den folgenden Code mit mehreren Benutzern zu testen. Da es sich bei der Klasse jedoch um einen von Spring verwalteten Singleton handelt, gibt es nur ein erstelltes Objekt und mehrere Threads versuchen, auf dasselbe Objekt zuzugreifen.

Aufgrund inkonsistenter Ausgabezeichenfolgen. Versuchen Sie, dieses Problem zu lösen, indem Sie das synchronisierte Schlüsselwort in der Applogger-Methode verwenden. Es funktioniert wie erwartet. Aber wir müssen Kompromisse bei der Leistung eingehen.

Wie gehe ich mit Singleton-Beans in einer Multithread-Umgebung um und erhalte eine bessere Leistung durch Änderung der Instanzvariablen (Stringbuilder)?

BearbeitenCode und fügen Sie die Aggregatlogger-Methode hinzu. Diese Methode aggregiert die Zeichenfolge zu einem vorhandenen Stringbuilder, der auf Klassenebene deklariert wurde, sodass der Stringbuilder über aggregierte Protokolle von den Methoden applogger undaggregatlogger verfügt.

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

Lösung

Ihr Design ist falsch, bitte verzeihen Sie mir, dass ich so unverblümt bin. Selbst innerhalb einer Geschäftstransaktion, die Sie protokollieren möchten, kann es mehrere Anwendungsschichten geben, die mehrere Vorgänge in mehreren Threads ausführen. Warum muss das alles in einer Protokollnachricht enthalten sein? Normalerweise protokollieren Sie alle Nachrichten unter Verwendung einer Kunden- und/oder Transaktions-ID oder einer anderen ID, die die logische Entität, die Sie verfolgen und protokollieren möchten, korrekt identifiziert. Die meisten Protokollierungs-Frameworks verwenden eine Art Mapped Diagnostic Context (MDC)das. Unabhängig davon, ob Sie sich bei der Konsole oder einer Datenbank oder einem Protokollaggregator wie Logstash oder Graylog anmelden, können Sie nach der Entität oder Transaktion, an der Sie interessiert sind, suchen, filtern und aggregieren, um alle entsprechenden Protokollmeldungen zu finden. Es ist nicht erforderlich, sie alle in einer Protokollnachricht zusammenzufassen.

Anstatt Ihren Kerncode mit Protokollanweisungen zu verschmutzen, können Sie natürlich Aspekte für die Protokollierung nutzen. Einer der Hauptvorteile von AOP besteht darin, übergreifende Probleme wie die Protokollierung aufzudecken. Aber man sollte es richtig machen. Ihr Singleton-Aspekt verwendet also entweder MDC oder führt seine eigene Buchhaltung in einer Art Zuordnung durch. Ich empfehle, die Tools zu verwenden, die Ihr Protokollierungs-Framework bereits bereitstellt, und sich auf das zu konzentrieren, was es am besten kann, nämlich das Abfangen der richtigen Verbindungspunkte.

Da die Leistung auch eines Ihrer Anliegen ist, möchten Sie möglicherweise Ihr Protokollierungsframework für die asynchrone Protokollierung konfigurieren, um Ihre Anwendung schneller und reaktionsfähiger zu machen. Auch die Protokollierung in einer Datei ist im Allgemeinen schneller als die Protokollierung in der Konsole. Vielleicht liefert Ihnen dieses GitHub-Repository mit seiner interessanten Readme-Datei und den JMH-Benchmarks interessante Informationen zusätzlich zu dem, was wir hier besprechen. Falls Sie Deutsch sprechen, vor ein paar Tagen auf diesem Heise.de-Blog. Der deutsche Inhalt dieses Artikels entspricht im Wesentlichen der englischen Readme-Datei, ich wollte lediglich meine Quellen angeben.

Unabhängig davon wird die Protokollaggregations-ID bei Verwendung der asynchronen Protokollierung in einem Multithread-Kontext wichtiger.

Das obige ist der detaillierte Inhalt vonWie kann man einen Singleton-Bean-Thread sicher machen und eine bessere Leistung in Java erzielen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen