8074002: java.time.ZoneId.systemDefault() should be faster

Cache ZoneId inside TimeZone object

Reviewed-by: scolebourne, rriggs, dfuchs
This commit is contained in:
Peter Levart 2015-05-17 18:49:21 +02:00
parent 30bcd97f81
commit f79ca89ac7

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -293,6 +293,7 @@ abstract public class TimeZone implements Serializable, Cloneable {
throw new NullPointerException(); throw new NullPointerException();
} }
this.ID = ID; this.ID = ID;
this.zoneId = null; // invalidate cache
} }
/** /**
@ -544,7 +545,23 @@ abstract public class TimeZone implements Serializable, Cloneable {
* @since 1.8 * @since 1.8
*/ */
public ZoneId toZoneId() { public ZoneId toZoneId() {
ZoneId zId = zoneId;
if (zId == null) {
zoneId = zId = toZoneId0();
}
return zId;
}
private ZoneId toZoneId0() {
String id = getID(); String id = getID();
TimeZone defaultZone = defaultTimeZone;
// are we not defaultTimeZone but our id is equal to default's?
if (defaultZone != this &&
defaultZone != null && id.equals(defaultZone.getID())) {
// delegate to default TZ which is effectively immutable
return defaultZone.toZoneId();
}
// derive it ourselves
if (ZoneInfoFile.useOldMapping() && id.length() == 3) { if (ZoneInfoFile.useOldMapping() && id.length() == 3) {
if ("EST".equals(id)) if ("EST".equals(id))
return ZoneId.of("America/New_York"); return ZoneId.of("America/New_York");
@ -710,7 +727,12 @@ abstract public class TimeZone implements Serializable, Cloneable {
sm.checkPermission(new PropertyPermission sm.checkPermission(new PropertyPermission
("user.timezone", "write")); ("user.timezone", "write"));
} }
defaultTimeZone = zone; // by saving a defensive clone and returning a clone in getDefault() too,
// the defaultTimeZone instance is isolated from user code which makes it
// effectively immutable. This is important to avoid races when the
// following is evaluated in ZoneId.systemDefault():
// TimeZone.getDefault().toZoneId().
defaultTimeZone = (zone == null) ? null : (TimeZone) zone.clone();
} }
/** /**
@ -735,9 +757,7 @@ abstract public class TimeZone implements Serializable, Cloneable {
public Object clone() public Object clone()
{ {
try { try {
TimeZone other = (TimeZone) super.clone(); return super.clone();
other.ID = ID;
return other;
} catch (CloneNotSupportedException e) { } catch (CloneNotSupportedException e) {
throw new InternalError(e); throw new InternalError(e);
} }
@ -759,6 +779,12 @@ abstract public class TimeZone implements Serializable, Cloneable {
* @serial * @serial
*/ */
private String ID; private String ID;
/**
* Cached {@link ZoneId} for this TimeZone
*/
private transient ZoneId zoneId;
private static volatile TimeZone defaultTimeZone; private static volatile TimeZone defaultTimeZone;
static final String GMT_ID = "GMT"; static final String GMT_ID = "GMT";