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 
main(String[] args)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 
Bug6335238()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 
run()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 
run()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 }
164