[concurrency-interest] ThreadLocalRandom.nextSecondarySeed() re-initializes TLR's seed (original) (raw)

Peter Levart peter.levart at gmail.com
Fri Jun 20 08:42:31 UTC 2014


Hi Doug,

On 06/19/2014 02:02 PM, Doug Lea wrote:

On 06/19/2014 04:48 AM, Peter Levart wrote:

Or, even better, why not just using the next value from the "seeder" sequence for the initial value of "secondary" seed and avoid interaction with TLR's main seed/probe: Thanks! Or better, just use mix32:

+ if ((r = (int)mix64(seeder.getAndAdd(SEEDERINCREMENT))) == 0) => if ((r = mix32(seeder.getAndAdd(SEEDERINCREMENT))) == 0)

That's right.

I committed this to jsr166 cvs. As you noted, this only addresses an uncommon performance glitch.

Not so performance as the "expected" behaviour. I'm assuming the aim of TLR.nextSecondarySeed() as a java.util.concurrent private thread-local source of random numbers is:

I was concerned about the last point only.

I don't have any further ideas since we discussed last year the tradeoffs between computing decent quality initial seeds versus class-loading. I still think we have the best practical compromise in place.

This pertains to the other thread (ThreadLocalRandom clinit troubles) started by Martin Buchholz, right? He's making a valid point. The "seeder" static field is still uninitialized during either NetworkInterface class initialization (as a result of NetworkInterface.getNetworkInterfaces() call) or during SecureRandom.getSeed() call. Either of which can execute user code in some configurations which might in turn use ThreadLocalRandom. If this happens, TLR.current() throws a NPE. I proposed a re-arrangement of class initialization that allows TLR to be fully functional even during it's initialization, albeit with a less randomized seed, and does not change the behaviour otherwise (since it triggers re-initialization at the end). See the proposed patch in the other thread.

Regards, Peter

-Doug

} UNSAFE.putInt(t, SECONDARY, r);

Regards, Peter On 06/19/2014 10:37 AM, Peter Levart wrote: Hi, I noticed an inconsistency in calling TLR.localInit() method. Everywhere it's called conditionaly if thread-local "probe" is zero except in TLR.nextSecondarySeed() where it's called if "secondary" seed is zero. This re-initializes the "probe" and "seed" even though they might have already been initialized. It's not a big deal, because this happens at most once per thread, but it would be more consistent to call localInit() conditionaly, I think:

diff -r 5b45a5efe417 src/share/classes/java/util/concurrent/ThreadLocalRandom.java --- a/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Tue May 20 10:11:23 2014 +0400 +++ b/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Thu Jun 19 10:34:18 2014 +0200 @@ -1034,7 +1034,8 @@ r ^= r << 5; } else { - localInit(); + if (UNSAFE.getInt(t, PROBE) == 0) + localInit(); if ((r = (int)UNSAFE.getLong(t, SEED)) == 0) r = 1; // avoid zero }

Regards, Peter


Concurrency-interest mailing list Concurrency-interest at cs.oswego.edu http://cs.oswego.edu/mailman/listinfo/concurrency-interest



More information about the core-libs-dev mailing list