The current state of this change follows. Swamy, please review. # HG changeset patch # User martin # Date 1240096219 25200 # Node ID 8b326aebb981265a99ed96355efe28f8c1b0a0c0 # Parent 536bac6e2774d9ff8a319d5276dddc87b7994650 6278014:java.util.logging.LogRecord.getThreadID() should provide real thread id Reviewed-by: swamyv Summary: Make j.u.l. thread id a copy of Thread's id, for small values of thread id.
diff --git a/src/share/classes/java/util/logging/LogRecord.java b/src/share/classes/java/util/logging/LogRecord.java --- a/src/share/classes/java/util/logging/LogRecord.java +++ b/src/share/classes/java/util/logging/LogRecord.java @@ -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; } diff --git a/test/java/util/logging/LoggerSubclass.java b/test/java/util/logging/LoggerSubclass.java --- a/test/java/util/logging/LoggerSubclass.java +++ b/test/java/util/logging/LoggerSubclass.java @@ -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()); Martin On Tue, Apr 14, 2009 at 15:34, Martin Buchholz <marti...@google.com> wrote: > Jeremy pointed out that a bug for this already exists. > > Synopsis java.util.logging.LogRecord.getThreadID() should provide > real thread id > http://bugs.sun.com/view_bug.do?bug_id=6278014 > > Martin > > > On Tue, Apr 14, 2009 at 14:45, Martin Buchholz <marti...@google.com> wrote: >> Synopsis: >> Correlating LogRecord ThreadIDs with run-of-the-mill Thread ids >