RFR: JDK-8240340: java/lang/management/ThreadMXBean/Locks.java is buggy
David Holmes
david.holmes at oracle.com
Mon Mar 9 04:15:58 UTC 2020
Hi Alex,
On 6/03/2020 4:54 am, Alex Menkov wrote:
> Hi David,
>
> Thanks you for the review.
>
> On 03/04/2020 17:50, David Holmes wrote:
>> Hi Alex,
>>
>> On 5/03/2020 10:30 am, Alex Menkov wrote:
>>> Hi all,
>>>
>>> please review the fix for
>>> https://bugs.openjdk.java.net/browse/JDK-8240340
>>> webrev:
>>> http://cr.openjdk.java.net/~amenkov/jdk15/ThreadMXBean_Locks_test/webrev/
>>>
>>>
>>> changes:
>>> - assertThreadState method: don't re-read thread state throwing
>>> exception (as we got weird error like "Thread WaitingThread is at
>>> WAITING state but is expected to be in Thread.State = WAITING");
>>> - added proper test shutdown on error (made all threads "daemon",
>>> interrupt waiting thread if CheckerThread throws exception);
>>> - if CheckerThread detects error, propagate the exception to main
>>> thread;
>>
>> The test changes seem fine.
>>
>>> - fixed LockFreeLogger class - it should work for logging from
>>> several threads, but it doesn't. I prefer to simplify it just to keep
>>> ConcurrentLinkedQueue<String>.
>>> LockFreeLogger is also used by ThreadMXBeanStateTest test, but only
>>> by a single thread.
>>
>> I don't understand your changes here as you've completely changed the
>> intended design of the logger. The original accumulates log entries
>> per-thread and then spits them all out (though I'm not clear on the
>> exact ordering - I don't how to read that stream stuff). The new code
>> just creates a single queue of log records interleaving entries from
>> different threads. The simple logger may be all that is needed but it
>> seems quite different to the intent of the original.
>
> Testing changes in the test I discovered that there is something wrong
> with the logger - it printed only part of the records, so I have to look
> at the LockFreeLogger class and I don't understand how it was supposed
> to work.
> About ordering in cumulative log: each record has Integer which used to
> sort log entries from all threads (i.e. records from different threads
> are printed at the order which log() was called).
> Looking at allRecords/records stuff I don't understand how it should be
> used. To get logs from different threads in one logger, we needs one
> instance. So we create LockFreeLogger (in main thread) and ctor creates
> ThreadLocal record and register it in allRecords. Logging from main
> thread works fine, but if any other thread tries to log, 1st log() call
> creates its own ThreadLocal records (by records.get()) and log records
> from this thread go there. But this ThreadLocal records is not
> registered in allRecords, so this logging won't be included in final log.
> Looks like we need to change log() to something like
>
> Map<Integer, String> recs = records.get();
> if (recs.isEmpty()) {
> allRecords.add(recs);
> }
> recs.put(id, String.format(format, params));
Yep good catch - this logger was completely broken.
> But all this stuff do exactly the same as simple ConcurrentLinkedQueue
> (i.e. lock free ordered list).
> At least I don't see other rationale in the stuff.
I'm not certain of intent with the original but I'd always want to see
log entries in chronological order - which is what we now clearly have.
Thanks,
David
> --alex
>
>>
>> Thanks,
>> David
>>
>>> --alex
More information about the serviceability-dev
mailing list