DateFormat 클래스는 비 스레드 안전 클래스입니다. Javadocs 문서는 "날짜 형식을 동기화 할 수 없습니다. 각 스레드에 대한 독립 날짜 형식을 만드는 것이 좋습니다. 여러 스레드가 동시에 날짜 형식에 액세스하면 동기 코드 블록을 외부에 추가해야합니다."
다음 코드는 스레드 환경에서 DateFormat을 사용하여 문자열 날짜를 날짜 개체로 변환하는 방법을 보여줍니다. 시스템이 현지 언어와 국가를 여러 번 얻을 필요가 없기 때문에 날짜 형식을 얻기위한 예제를 작성하는 것이 더 효율적입니다.
공개 클래스 DateFormAttest {개인 최종 DateFormat 형식 = New SimpleDateFormat ( "yyyymmdd");
이 코드는 스레드되지 않았습니다. 여러 스레드를 통해 호출 할 수 있습니다. 다음 코드에서는 두 개의 스레드가있는 스레드 풀을 만들었고 그 후 5 개의 데이트 전환 작업을 제출했습니다.
최종 날짜 formattest t = new dateformattest (); callable <date> task = new Callable <date> () {public date () rows {return t.convert ( "20100811";}}}; 스레드의 경우 = 0; exec.submit (task)); .out.println (result.get cure);}
코드의 작동 결과는 우리가 원했던 것과 같지 않으며, 올바른 날짜를 출력하고 때로는 출력 오류 (예 : 7 월 31 일 00:00:00 BST 2012), 때로는 숫자 formatexception을 던지기도합니다!
DateFormat 클래스를 동시에 사용하는 방법
스레드 보안시 DateFormat 클래스를 사용할 수있는 여러 가지 방법을 가질 수 있습니다.
1. 동기
가장 쉬운 방법은 날짜 변환 전에 dateformat 객체를 잠그는 것입니다. 이 방법을 사용하면 하나의 스레드 만 한 번에 dateformat 객체에 액세스 할 수 있지만 다른 스레드는 대기 할 수 있습니다.
public date convert (문자열 소스) parseexception {synchronized (format) {date d = format.pars (source);
2. ThreadLocal을 사용하십시오
또 다른 방법은 DateFormat 객체를 수용하기 위해 ThreadLocal 변수를 사용하는 것입니다. 즉, 각 스레드에는 자체에 속하는 사본이 있으며 다른 스레드가 해제 될 때까지 기다릴 필요가 없습니다. 이 방법은 동기 블록을 사용하는 것보다 더 효율적입니다.
공개 클래스 DateFormAttest {private static final strook <df = new ThreadLocal <DateFormat> () {{@OverRide Protected DateFormat () return new SimpleDateFormat ( "yyyymmdd");}}; 날짜 d = df.get ().
3. 조다-타임
Joda-Time은 훌륭한 오픈 소스 JDK 날짜이며 Calendar API 대안입니다.
org.joda.time.dateTime; convert (string source) {dateTime d = fmt.parsedAteTime (source); todate ();