'SimpleDateFormat 관련 버그 리포팅'에 대해 다시 의견 답니다.
- 작성자 :
- 박*욱
- 작성일 :
- 2010-05-11 02:17:32
- 조회수 :
- 3,410
- 구분 :
- 실행환경
- 진행상태 :
- 완료
Q
안녕하세요. 올려주신 답변을 잘 보았습니다.
그러나 몇 가지 의견이 있어 다시 글을 남깁니다.
1. 일단'TypeHandler가 synchronized 처리가 되어 스레드 안전하게 구현되었기 때문에'라고 하셨는데, TypeHandler가 어느 시점에서 synchronized 처리가 됐다는 말씀이신지요? TypeHandler를 호출하는 측에서 synchronized 됐다면 static 영역에 존재하는 SDF를 호출하는 것과는 전혀 별개로 스레드 안전하지 않은 문제가 여전히 발생할 것 입니다.
2. TypeHandler는 데이터 I/O 시에 데이터의 타입 변환을 목적으로 사용하는 데, 이런 타입 변환 목적으로 된 로직을 synchronized 로 처리한 다는 것 자체가 무리가 있다고 생각합니다.
3. 말씀하신 TypeHandler를 구현한 iBatis 소스 중에서 동일하게 SDF를 사용해 타입 변환을 하는 코드가 나옵니다.
클래스 명은 SqlTimeTypeHandler 입니다. 여기에서 valueOf() 코드를 보면 SDF를 사용해서 포맷은 변경하는 코드가 나오는데, static util 함수로 뽑아 내기는 했지만 여기서는 매 호출 시마다 SDF를 정상적으로 생성해서 사용하고 있습니다. 말씀하신 대로 synchronized 처리가 되면 iBatis 기본 구현체에서도 동일하게 처리하지 않은 이유가 있을까요?
public class SqlTimeTypeHandler extends BaseTypeHandler implements TypeHandler {
public Object valueOf(String s) {
return SimpleDateFormatter.format(DATE_FORMAT, s);
}
}
public class SimpleDateFormatter {
public static Date format(String format, String datetime) {
try {
return new SimpleDateFormat(format).parse(datetime);
} catch (ParseException e) {
throw new SqlMapException("Error parsing default null value date. Format must be '" + format + "'. Cause: " + e);
}
}
}
그러나 몇 가지 의견이 있어 다시 글을 남깁니다.
1. 일단'TypeHandler가 synchronized 처리가 되어 스레드 안전하게 구현되었기 때문에'라고 하셨는데, TypeHandler가 어느 시점에서 synchronized 처리가 됐다는 말씀이신지요? TypeHandler를 호출하는 측에서 synchronized 됐다면 static 영역에 존재하는 SDF를 호출하는 것과는 전혀 별개로 스레드 안전하지 않은 문제가 여전히 발생할 것 입니다.
2. TypeHandler는 데이터 I/O 시에 데이터의 타입 변환을 목적으로 사용하는 데, 이런 타입 변환 목적으로 된 로직을 synchronized 로 처리한 다는 것 자체가 무리가 있다고 생각합니다.
3. 말씀하신 TypeHandler를 구현한 iBatis 소스 중에서 동일하게 SDF를 사용해 타입 변환을 하는 코드가 나옵니다.
클래스 명은 SqlTimeTypeHandler 입니다. 여기에서 valueOf() 코드를 보면 SDF를 사용해서 포맷은 변경하는 코드가 나오는데, static util 함수로 뽑아 내기는 했지만 여기서는 매 호출 시마다 SDF를 정상적으로 생성해서 사용하고 있습니다. 말씀하신 대로 synchronized 처리가 되면 iBatis 기본 구현체에서도 동일하게 처리하지 않은 이유가 있을까요?
public class SqlTimeTypeHandler extends BaseTypeHandler implements TypeHandler {
public Object valueOf(String s) {
return SimpleDateFormatter.format(DATE_FORMAT, s);
}
}
public class SimpleDateFormatter {
public static Date format(String format, String datetime) {
try {
return new SimpleDateFormat(format).parse(datetime);
} catch (ParseException e) {
throw new SqlMapException("Error parsing default null value date. Format must be '" + format + "'. Cause: " + e);
}
}
}
A
안녕하세요.. 박찬욱님..
다시 한번 말씀드리지만 static 자체가 문제가 되는 것이 아니라 static으로 선언된 객체가 여러 thread에 의해 호출될 때 별도의 synchronized와 같은 thread-safe한 구현이 되지 않은 경우.. 해당 객체의 상태(멤버 변수의 값 등)가 기대했던 값이 나오지 않는 문제입니다.
말씀하신 것 처럼.. sdf 자체가 thread-safe하게 구현되어 있지 않기 때문에.. 일반적인 경우 static으로 선언하여 사용하고 웹과 같은 thread 기반에서는 운영한다면 문제가 발생합니다.
그러나 static하게 선언된 sdf의 메소드들을 호출하는 부분이 synchronized 되도록 구현되어 있다면 여러 thread가 동시에 호출하더라도 호출에 대한 동기화가 되기 때문에 서로 간섭되지 않습니다...
추가적으로 typeHandler 호출 부분은 iBatis의 SqlMapClient에 의해 thread-safe하게 처리되기 때문에 typeHandler 호출이 서로 간섭되지 않습니다. (SqlMapClient가 thread-safe하게 구현된 부분은 iBatis쪽 문서를 참조 바람)
마지막으로 SqlTimeTypeHandler의 예를 들어주셨는데.. 해당 예를 하나의 예이지 절대적인 구현에 답은 아닌 것 같습니다.
그럼.. 즐거운 하루되십시오.
감사합니다.
다시 한번 말씀드리지만 static 자체가 문제가 되는 것이 아니라 static으로 선언된 객체가 여러 thread에 의해 호출될 때 별도의 synchronized와 같은 thread-safe한 구현이 되지 않은 경우.. 해당 객체의 상태(멤버 변수의 값 등)가 기대했던 값이 나오지 않는 문제입니다.
말씀하신 것 처럼.. sdf 자체가 thread-safe하게 구현되어 있지 않기 때문에.. 일반적인 경우 static으로 선언하여 사용하고 웹과 같은 thread 기반에서는 운영한다면 문제가 발생합니다.
그러나 static하게 선언된 sdf의 메소드들을 호출하는 부분이 synchronized 되도록 구현되어 있다면 여러 thread가 동시에 호출하더라도 호출에 대한 동기화가 되기 때문에 서로 간섭되지 않습니다...
추가적으로 typeHandler 호출 부분은 iBatis의 SqlMapClient에 의해 thread-safe하게 처리되기 때문에 typeHandler 호출이 서로 간섭되지 않습니다. (SqlMapClient가 thread-safe하게 구현된 부분은 iBatis쪽 문서를 참조 바람)
마지막으로 SqlTimeTypeHandler의 예를 들어주셨는데.. 해당 예를 하나의 예이지 절대적인 구현에 답은 아닌 것 같습니다.
그럼.. 즐거운 하루되십시오.
감사합니다.