Java 동시성에서 SimpleDateFormat 및 Random을 사용하는 방법

1. SimpleDateFormat 클래스

1. SimpleDateFormat의 잘못된 사용

@Slf4j
public class DateUtil {
    
    

    private final static DateTimeFormatter yymmddhhmmss = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private final static DateTimeFormatter yymmdd = DateTimeFormatter.ofPattern("yyyyMMdd");
    
public static LocalDateTime getDate(String date) {
    
    
        return LocalDateTime.parse(date, yymmddhhmmss);
    }
}

여러 스레드가 동시에 getDate 메소드를 호출하는 경우 dateFormat에서 사용하는 내부 데이터 구조가 동시 액세스로 인해 손상될 수 있고 동시성이 안전하지 않기 때문에 결과가 혼란스러울 수 있습니다.

물론 동기화를 사용할 수도 있지만 비용이 많이 들고, 필요할 때 부분적인 SimpleDateFormat 객체를 생성할 수도 있지만 이는 너무 낭비입니다.

2. SimpleDateFormat의 올바른 사용

각 스레드에 대해 새 SimpleDateFormat 인스턴스를 만듭니다. 이렇게 하면 각 스레드가 자체 SimpleDateFormat 인스턴스를 갖게 되어 다중 스레드 환경에서 스레드로부터 안전해집니다.

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateFormatExample {
    
    
    public static final ThreadLocal<SimpleDateFormat> dateFormat =
            ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));

    public static void main(String[] args) {
    
    
        // 获取当前线程的 SimpleDateFormat 实例
        SimpleDateFormat threadDateFormat = dateFormat.get();

        try {
    
    
            // 格式化当前日期
            String dateStamp = threadDateFormat.format(new Date());
            System.out.println("Formatted Date: " + dateStamp);
        } finally {
    
    
            // 清理 ThreadLocal 中的内容,防止内存泄漏
            dateFormat.remove();
        }
    }
}

2. 무작위 클래스

Java의 java.util.Random 클래스는 해당 메소드가 다중 스레드 환경에서 동기화되므로 스레드로부터 안전합니다. 그러나 동기화로 인해 경합과 대기가 발생하므로 여러 스레드가 공유 난수 생성기를 기다려야 하는 경우 성능 문제가 발생할 수 있습니다.

멀티 스레드 환경에서 보다 효율적으로 난수를 생성하려면 java.util.concurrent.ThreadLocalRandom 클래스를 사용할 수 있습니다. ThreadLocalRandom은 Java 7에서 도입되었으며 ThreadLocal의 변형으로, 각 스레드에 독립적인 난수 생성기 인스턴스를 제공하여 경쟁을 피하고 성능을 향상시킵니다.

import java.util.concurrent.ThreadLocalRandom;

public class RandomNumberExample {
    
    
    public static void main(String[] args) {
    
    
        int upperBound = 100;
        int random = ThreadLocalRandom.current().nextInt(upperBound);
        System.out.println("Random number between 0 and " + (upperBound - 1) + ": " + random);
    }
}

Guess you like

Origin blog.csdn.net/FLGBgo/article/details/132103784