>Java >싱글톤 빈 스레드를 안전하게 만들고 Java에서 더 나은 성능을 얻는 방법은 무엇입니까?

싱글톤 빈 스레드를 안전하게 만들고 Java에서 더 나은 성능을 얻는 방법은 무엇입니까?

王林
王林앞으로
2024-02-09 09:00:201050검색

Java 개발에서 싱글톤 패턴은 클래스에 인스턴스 객체가 하나만 있도록 보장하기 위해 일반적으로 사용되는 디자인 패턴입니다. 그러나 멀티 스레드 환경에서 싱글톤 패턴을 사용하면 스레드 안전 문제가 발생하여 프로그램의 성능과 정확성에 영향을 미칠 수 있습니다. 그렇다면 싱글톤 Bean 스레드를 안전하게 만들고 Java에서 더 나은 성능을 얻으려면 어떻게 해야 할까요? PHP 편집자 Yuzai가 다음과 같은 측면을 소개하고 답변해 드립니다.

질문 내용

아래 코드를 여러 사용자를 대상으로 테스트하려고 합니다. 그러나 클래스는 Spring에 의해 관리되는 싱글톤이므로 생성된 객체는 하나만 있고 여러 스레드가 동일한 객체에 액세스하려고 합니다.

일관되지 않은 출력 문자열로 인해. applogger 메소드에서 동기화 키워드를 사용하여 이 문제를 해결해 보세요. 예상대로 작동하고 있습니다. 하지만 성능에 있어서는 타협이 필요합니다.

멀티 스레드 환경에서 싱글톤 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;
    }
    
}

Solution

디자인이 잘못되었습니다. 너무 무뚝뚝한 점 양해 부탁드립니다. 기록하려는 하나의 비즈니스 트랜잭션 내에도 여러 스레드에서 여러 작업을 수행하는 여러 애플리케이션 계층이 있을 수 있습니다. 왜 이 모든 것이 하나의 로그 메시지에 있어야 합니까? 일반적으로 일종의 고객 및/또는 거래 ID를 사용하거나 추적하고 기록하려는 논리적 엔터티를 올바르게 식별하는 모든 메시지를 기록합니다. 대부분의 로깅 프레임워크는 일종의 MDC(매핑된 진단 컨텍스트)를 사용합니다. 콘솔이나 데이터베이스 또는 Logstash나 Graylog와 같은 로그 수집기에 로그인하더라도 관심 있는 엔터티나 트랜잭션을 기준으로 검색, 필터링 및 집계하여 해당하는 모든 로그 메시지를 찾을 수 있습니다. 하나의 로그 메시지에 모두 넣을 필요가 없습니다.

물론 로그 문으로 핵심 코드를 오염시키는 대신 로깅 측면을 활용할 수 있습니다. 로깅과 같은 교차 문제를 해결하는 것은 AOP의 주요 장점 중 하나입니다. 하지만 제대로 해야 합니다. 따라서 싱글톤 측면은 MDC를 사용하거나 일종의 매핑에서 자체 장부를 수행합니다. 로깅 프레임워크가 이미 제공하는 도구를 사용하고 측면이 가장 잘 수행하는 작업, 즉 올바른 조인 포인트를 가로채는 작업에 집중하도록 하는 것이 좋습니다.

성능도 고려 사항 중 하나이므로 비동기 로깅을 위한 로깅 프레임워크를 구성하여 애플리케이션의 속도와 응답성을 높일 수 있습니다. 파일에 로깅하는 것이 일반적으로 콘솔에 로깅하는 것보다 빠릅니다. 어쩌면 흥미로운 읽어보기 및 JMH 벤치마크가 포함된 이 GitHub 저장소는 여기서 논의한 내용 외에도 흥미로운 정보를 제공할 수도 있습니다. 혹시 독일어를 사용하신다면 며칠 전 이 Heise.de 블로그를 방문해 보세요. 이 기사의 독일어 내용은 기본적으로 영어 Readme와 동일합니다. 단지 출처를 제공하고 싶었을 뿐입니다.

아무튼 비동기 로깅을 사용하는 경우 멀티스레드 컨텍스트에서는 로그 집계 ID가 더욱 중요해집니다.

위 내용은 싱글톤 빈 스레드를 안전하게 만들고 Java에서 더 나은 성능을 얻는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 stackoverflow.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제