[java client] make DateFormat safe to use

Todd's error-prone patch discovered this problem in RowResult where
we use a static DateFormat from multiple threads. The recommended way
to do this is to use thread locals.

Change-Id: I6d18ba34db0a0782fd0b7401e9aea7ae59c6b6f6
Reviewed-on: http://gerrit.cloudera.org:8080/4429
Tested-by: Kudu Jenkins
Reviewed-by: Adar Dembo <a...@cloudera.com>
(cherry picked from commit b0b273e8271752b6eb04ba163981aad1c792e413)
Reviewed-on: http://gerrit.cloudera.org:8080/4603
Reviewed-by: Jean-Daniel Cryans <jdcry...@apache.org>
Tested-by: Jean-Daniel Cryans <jdcry...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/653ddf3a
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/653ddf3a
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/653ddf3a

Branch: refs/heads/branch-1.0.x
Commit: 653ddf3aae9787f3e2817af0618cab8882b16857
Parents: 80629bb
Author: Jean-Daniel Cryans <jdcry...@apache.org>
Authored: Thu Sep 15 16:21:23 2016 -0700
Committer: Jean-Daniel Cryans <jdcry...@apache.org>
Committed: Mon Oct 3 21:40:55 2016 +0000

----------------------------------------------------------------------
 .../java/org/apache/kudu/client/RowResult.java     | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/653ddf3a/java/kudu-client/src/main/java/org/apache/kudu/client/RowResult.java
----------------------------------------------------------------------
diff --git 
a/java/kudu-client/src/main/java/org/apache/kudu/client/RowResult.java 
b/java/kudu-client/src/main/java/org/apache/kudu/client/RowResult.java
index 0ef3e03..64871d9 100644
--- a/java/kudu-client/src/main/java/org/apache/kudu/client/RowResult.java
+++ b/java/kudu-client/src/main/java/org/apache/kudu/client/RowResult.java
@@ -39,10 +39,17 @@ import java.util.TimeZone;
 public class RowResult {
 
   private static final int INDEX_RESET_LOCATION = -1;
-  private static final DateFormat DATE_FORMAT = new 
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
-  static {
-    DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
-  }
+
+  // Thread local DateFormat since they're not thread-safe.
+  private static final ThreadLocal<DateFormat> DATE_FORMAT = new 
ThreadLocal<DateFormat>(){
+    @Override
+    protected DateFormat initialValue() {
+      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+      sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
+      return sdf;
+    }
+  };
+
   private static final long MS_IN_S = 1000L;
   private static final long US_IN_S = 1000L * 1000L;
   private int index = INDEX_RESET_LOCATION;
@@ -513,7 +520,7 @@ public class RowResult {
     long tsMillis = timestamp / MS_IN_S;
     long tsMicros = timestamp % US_IN_S;
     StringBuffer formattedTs = new StringBuffer();
-    DATE_FORMAT.format(new Date(tsMillis), formattedTs, new FieldPosition(0));
+    DATE_FORMAT.get().format(new Date(tsMillis), formattedTs, new 
FieldPosition(0));
     formattedTs.append(String.format(".%06dZ", tsMicros));
     return formattedTs.toString();
   }

Reply via email to