6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
Summary: Make j.u.l. thread id a copy of Thread's id, for small values of thread id.
Reviewed-by: alanb
--- a/jdk/src/share/classes/java/util/logging/LogRecord.java Mon Apr 20 21:53:38 2009 -0700
+++ b/jdk/src/share/classes/java/util/logging/LogRecord.java Mon Apr 20 21:57:01 2009 -0700
@@ -25,6 +25,8 @@
package java.util.logging;
import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
import java.io.*;
/**
@@ -64,9 +66,24 @@
*/
public class LogRecord implements java.io.Serializable {
- private static long globalSequenceNumber;
- private static int nextThreadId=10;
- private static ThreadLocal<Integer> threadIds = new ThreadLocal<Integer>();
+ private static final AtomicLong globalSequenceNumber
+ = new AtomicLong(0);
+
+ /**
+ * The default value of threadID will be the current thread's
+ * thread id, for ease of correlation, unless it is greater than
+ * MIN_SEQUENTIAL_THREAD_ID, in which case we try harder to keep
+ * our promise to keep threadIDs unique by avoiding collisions due
+ * to 32-bit wraparound. Unfortunately, LogRecord.getThreadID()
+ * returns int, while Thread.getId() returns long.
+ */
+ private static final int MIN_SEQUENTIAL_THREAD_ID = Integer.MAX_VALUE / 2;
+
+ private static final AtomicInteger nextThreadId
+ = new AtomicInteger(MIN_SEQUENTIAL_THREAD_ID);
+
+ private static final ThreadLocal<Integer> threadIds
+ = new ThreadLocal<Integer>();
/**
* @serial Logging message level
@@ -123,6 +140,23 @@
private transient ResourceBundle resourceBundle;
/**
+ * Returns the default value for a new LogRecord's threadID.
+ */
+ private int defaultThreadID() {
+ long tid = Thread.currentThread().getId();
+ if (tid < MIN_SEQUENTIAL_THREAD_ID) {
+ return (int) tid;
+ } else {
+ Integer id = threadIds.get();
+ if (id == null) {
+ id = nextThreadId.getAndIncrement();
+ threadIds.set(id);
+ }
+ return id;
+ }
+ }
+
+ /**
* Construct a LogRecord with the given level and message values.
* <p>
* The sequence property will be initialized with a new unique value.
@@ -144,15 +178,8 @@
this.level = level;
message = msg;
// Assign a thread ID and a unique sequence number.
- synchronized (LogRecord.class) {
- sequenceNumber = globalSequenceNumber++;
- Integer id = threadIds.get();
- if (id == null) {
- id = new Integer(nextThreadId++);
- threadIds.set(id);
- }
- threadID = id.intValue();
- }
+ sequenceNumber = globalSequenceNumber.getAndIncrement();
+ threadID = defaultThreadID();
millis = System.currentTimeMillis();
needToInferCaller = true;
}
--- a/jdk/test/java/util/logging/LoggerSubclass.java Mon Apr 20 21:53:38 2009 -0700
+++ b/jdk/test/java/util/logging/LoggerSubclass.java Mon Apr 20 21:57:01 2009 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6830220
+ * @bug 6830220 6278014
* @summary Test Logger subclasses
*/
@@ -68,6 +68,8 @@
l.getSequenceNumber());
equal(lastThreadID.get(),
l.getThreadID());
+ equal((int) Thread.currentThread().getId(),
+ l.getThreadID());
}
lastSequenceNumber.set(l.getSequenceNumber());
lastThreadID.set(l.getThreadID());