001// Copyright 2009 by Basil Vandegriend. All rights reserved. 002 003package com.basilv.examples.concurrency; 004 005import java.text.*; 006import java.util.Date; 007 008/** 009 * Parses dates and tracks the results. 010 * This class deliberately contains a number of concurrency defects. 011 */ 012public class DateProcessor 013{ 014 private static DateProcessor instance; 015 016 public static DateProcessor getInstance() { 017 if (instance == null) { 018 synchronized(DateProcessor.class) { 019 if (instance == null) { 020 instance = new DateProcessor(); 021 } 022 } 023 } 024 return instance; 025 } 026 027 static void setInstanceForTesting(DateProcessor newInstance) { 028 instance = newInstance; 029 } 030 031 private static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd"); 032 033 private long datesProcessedCount = 0; 034 private long datesValidCount = 0; 035 036 /** 037 * Try to parse the supplied input into a date, 038 * returning null if the input is not a valid date in format yyyy-MM-dd 039 */ 040 public Date processDate(String input) { 041 datesProcessedCount++; 042 try { 043 Date date = dateFormatter.parse(input); 044 datesValidCount++; 045 return date; 046 } catch (ParseException e) { 047 return null; 048 } 049 } 050 051 public long getDatesProcessedCount() { 052 return datesProcessedCount; 053 } 054 055 public long getDatesValidCount() { 056 return datesValidCount; 057 } 058 059}