1 /*
   2  * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test 1.1 06/01/24
  26  * @bug 6335238
  27  * @summary Make sure that both the original and cloned SimpleDateFormat coexistindependently and don't cut off each other.
  28  * @run main Bug6335238 10
  29  */
  30 
  31 import java.text.ParseException;
  32 import java.text.SimpleDateFormat;
  33 import java.util.Date;
  34 import java.util.Locale;
  35 import java.util.TimeZone;
  36 
  37 // Usage: java Bug6335238 [duration]
  38 public class Bug6335238 {
  39 
  40     static final long UTC_LONG = 974534460000L;
  41     static final String TIME_STRING = "2000/11/18 00:01:00";
  42     static SimpleDateFormat masterSdf;
  43     static int duration = 180;
  44     static boolean stopped = false;
  45     static boolean err = false;
  46 
  47     public static void main(String[] args) {
  48         if (args.length == 1) {
  49             duration = Math.max(10, Integer.parseInt(args[0]));
  50         }
  51         Locale savedLocale = Locale.getDefault();
  52         TimeZone savedTimeZone = TimeZone.getDefault();
  53 
  54         TimeZone.setDefault(TimeZone.getTimeZone("US/Pacific"));
  55         Locale.setDefault(Locale.US);
  56 
  57         masterSdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
  58 
  59         try {
  60             // Once it is used, DecimalFormat becomes not thread-safe.
  61             Date d = masterSdf.parse(TIME_STRING);
  62 
  63             new Bug6335238();
  64         } catch (Exception e) {
  65             System.err.println(e);
  66             err = true;
  67         } finally {
  68             TimeZone.setDefault(savedTimeZone);
  69             Locale.setDefault(savedLocale);
  70 
  71             if (err) {
  72                 throw new RuntimeException("Failed: Multiple DateFormat instances didn't work correctly.");
  73             } else {
  74                 System.out.println("Passed.");
  75             }
  76         }
  77     }
  78 
  79     public Bug6335238() {
  80         stopped = false;
  81 
  82         DateParseThread d1 = new DateParseThread();
  83         DateFormatThread d2 = new DateFormatThread();
  84         DateParseThread d3 = new DateParseThread();
  85         DateFormatThread d4 = new DateFormatThread();
  86 
  87         d1.start();
  88         d2.start();
  89         d3.start();
  90         d4.start();
  91 
  92         try {
  93             Thread.sleep(duration * 1000);
  94         }
  95         catch (Exception e) {
  96             System.err.println(e);
  97             err = true;
  98         }
  99 
 100         stopped = true;
 101     }
 102 
 103     class DateFormatThread extends Thread {
 104 
 105         public void run() {
 106             int i = 0;
 107 
 108             while (!stopped) {
 109                 SimpleDateFormat sdf;
 110                 synchronized (masterSdf) {
 111                     sdf = (SimpleDateFormat)masterSdf.clone();
 112                 }
 113 
 114                 i++;
 115                 String s = sdf.format(new Date(UTC_LONG));
 116 
 117                 if (!s.equals(TIME_STRING)) {
 118                     stopped = true;
 119                     err = true;
 120 
 121                     throw new RuntimeException("Formatting Date Error: counter=" +
 122                         i + ", Got<" + s + "> != Expected<" + TIME_STRING + ">");
 123                 }
 124             }
 125         }
 126     }
 127 
 128     class DateParseThread extends Thread {
 129 
 130         public void run() {
 131             int i = 0;
 132 
 133             while (!stopped) {
 134                 SimpleDateFormat sdf;
 135                 synchronized (masterSdf) {
 136                     sdf = (SimpleDateFormat)masterSdf.clone();
 137                 }
 138 
 139                 i++;
 140                 Date date;
 141                 try {
 142                     date = sdf.parse(TIME_STRING);
 143                     long t = date.getTime();
 144 
 145                     if (t != UTC_LONG) {
 146                         stopped = true;
 147                         err = true;
 148 
 149                         throw new RuntimeException("Parsing Date Error: counter=" +
 150                             i + " Got:" + t + "<" + sdf.format(date) +
 151                             "> != " + UTC_LONG);
 152                     }
 153                 }
 154                 catch (ParseException e) {
 155                     stopped = true;
 156                     err = true;
 157 
 158                     throw new RuntimeException(e);
 159                 }
 160             }
 161         }
 162     }
 163 }