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