提交 dc859491 编写于 作者: M mduigou

6611830: UUID thread-safety and performance improvements

Reviewed-by: mduigou, jjb, alanb, briangoetz, dholmes, peterjones
Contributed-by: NDaniel Aioanei <danielaioanei@google.com>
上级 98cb588a
...@@ -26,8 +26,6 @@ ...@@ -26,8 +26,6 @@
package java.util; package java.util;
import java.security.*; import java.security.*;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/** /**
* A class that represents an immutable universally unique identifier (UUID). * A class that represents an immutable universally unique identifier (UUID).
...@@ -90,36 +88,6 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> { ...@@ -90,36 +88,6 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
*/ */
private final long leastSigBits; private final long leastSigBits;
/*
* The version number associated with this UUID. Computed on demand.
*/
private transient int version = -1;
/*
* The variant number associated with this UUID. Computed on demand.
*/
private transient int variant = -1;
/*
* The timestamp associated with this UUID. Computed on demand.
*/
private transient volatile long timestamp = -1;
/*
* The clock sequence associated with this UUID. Computed on demand.
*/
private transient int sequence = -1;
/*
* The node number associated with this UUID. Computed on demand.
*/
private transient long node = -1;
/*
* The hashcode of this UUID. Computed on demand.
*/
private transient int hashCode = -1;
/* /*
* The random number generator used by this class to create random * The random number generator used by this class to create random
* based UUIDs. * based UUIDs.
...@@ -134,7 +102,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> { ...@@ -134,7 +102,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
private UUID(byte[] data) { private UUID(byte[] data) {
long msb = 0; long msb = 0;
long lsb = 0; long lsb = 0;
assert data.length == 16; assert data.length == 16 : "data must be 16 bytes in length";
for (int i=0; i<8; i++) for (int i=0; i<8; i++)
msb = (msb << 8) | (data[i] & 0xff); msb = (msb << 8) | (data[i] & 0xff);
for (int i=8; i<16; i++) for (int i=8; i<16; i++)
...@@ -276,11 +244,8 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> { ...@@ -276,11 +244,8 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
* @return The version number of this {@code UUID} * @return The version number of this {@code UUID}
*/ */
public int version() { public int version() {
if (version < 0) {
// Version is bits masked by 0x000000000000F000 in MS long // Version is bits masked by 0x000000000000F000 in MS long
version = (int)((mostSigBits >> 12) & 0x0f); return (int)((mostSigBits >> 12) & 0x0f);
}
return version;
} }
/** /**
...@@ -298,17 +263,13 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> { ...@@ -298,17 +263,13 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
* @return The variant number of this {@code UUID} * @return The variant number of this {@code UUID}
*/ */
public int variant() { public int variant() {
if (variant < 0) { // This field is composed of a varying number of bits.
// This field is composed of a varying number of bits // 0 - - Reserved for NCS backward compatibility
if ((leastSigBits >>> 63) == 0) { // 1 0 - The Leach-Salz variant (used by this class)
variant = 0; // 1 1 0 Reserved, Microsoft backward compatibility
} else if ((leastSigBits >>> 62) == 2) { // 1 1 1 Reserved for future definition.
variant = 2; return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62)))
} else { & (leastSigBits >> 63));
variant = (int)(leastSigBits >>> 61);
}
}
return variant;
} }
/** /**
...@@ -330,14 +291,10 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> { ...@@ -330,14 +291,10 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
if (version() != 1) { if (version() != 1) {
throw new UnsupportedOperationException("Not a time-based UUID"); throw new UnsupportedOperationException("Not a time-based UUID");
} }
long result = timestamp;
if (result < 0) { return (mostSigBits & 0x0FFFL) << 48
result = (mostSigBits & 0x0000000000000FFFL) << 48; | ((mostSigBits >> 16) & 0x0FFFFL) << 32
result |= ((mostSigBits >> 16) & 0xFFFFL) << 32; | mostSigBits >>> 32;
result |= mostSigBits >>> 32;
timestamp = result;
}
return result;
} }
/** /**
...@@ -360,10 +317,8 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> { ...@@ -360,10 +317,8 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
if (version() != 1) { if (version() != 1) {
throw new UnsupportedOperationException("Not a time-based UUID"); throw new UnsupportedOperationException("Not a time-based UUID");
} }
if (sequence < 0) {
sequence = (int)((leastSigBits & 0x3FFF000000000000L) >>> 48); return (int)((leastSigBits & 0x3FFF000000000000L) >>> 48);
}
return sequence;
} }
/** /**
...@@ -386,10 +341,8 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> { ...@@ -386,10 +341,8 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
if (version() != 1) { if (version() != 1) {
throw new UnsupportedOperationException("Not a time-based UUID"); throw new UnsupportedOperationException("Not a time-based UUID");
} }
if (node < 0) {
node = leastSigBits & 0x0000FFFFFFFFFFFFL; return leastSigBits & 0x0000FFFFFFFFFFFFL;
}
return node;
} }
// Object Inherited Methods // Object Inherited Methods
...@@ -438,13 +391,8 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> { ...@@ -438,13 +391,8 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
* @return A hash code value for this {@code UUID} * @return A hash code value for this {@code UUID}
*/ */
public int hashCode() { public int hashCode() {
if (hashCode == -1) { long hilo = mostSigBits ^ leastSigBits;
hashCode = (int)((mostSigBits >> 32) ^ return ((int)(hilo >> 32)) ^ (int) hilo;
mostSigBits ^
(leastSigBits >> 32) ^
leastSigBits);
}
return hashCode;
} }
/** /**
...@@ -460,9 +408,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> { ...@@ -460,9 +408,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
* otherwise * otherwise
*/ */
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (!(obj instanceof UUID)) if ((null == obj) || (obj.getClass() != UUID.class))
return false;
if (((UUID)obj).variant() != this.variant())
return false; return false;
UUID id = (UUID)obj; UUID id = (UUID)obj;
return (mostSigBits == id.mostSigBits && return (mostSigBits == id.mostSigBits &&
...@@ -494,23 +440,4 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> { ...@@ -494,23 +440,4 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
(this.leastSigBits > val.leastSigBits ? 1 : (this.leastSigBits > val.leastSigBits ? 1 :
0)))); 0))));
} }
/**
* Reconstitute the {@code UUID} instance from a stream (that is,
* deserialize it). This is necessary to set the transient fields to their
* correct uninitialized value so they will be recomputed on demand.
*/
private void readObject(java.io.ObjectInputStream in)
throws java.io.IOException, ClassNotFoundException {
in.defaultReadObject();
// Set "cached computation" fields to their initial values
version = -1;
variant = -1;
timestamp = -1;
sequence = -1;
node = -1;
hashCode = -1;
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册