Repository: kudu Updated Branches: refs/heads/master 1eb24183a -> af7f9c805
[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 <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/kudu/repo Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/b0b273e8 Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/b0b273e8 Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/b0b273e8 Branch: refs/heads/master Commit: b0b273e8271752b6eb04ba163981aad1c792e413 Parents: 1eb2418 Author: Jean-Daniel Cryans <[email protected]> Authored: Thu Sep 15 16:21:23 2016 -0700 Committer: Adar Dembo <[email protected]> Committed: Thu Sep 15 23:51:10 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/b0b273e8/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(); }
