[concurrency-interest] TLR Puzzle

Oleksandr Otenko oleksandr.otenko at oracle.com
Fri Feb 21 09:50:10 EST 2014


+1

Let's not forget that ThreadLocal that "can't be shared" is actually 
just the container. The container, yes, cannot be shared. But the value 
contained therein.... I can't recall any design consideration requiring 
or making it impossible to restrict access to the actual value, over 
which there is no control after ThreadLocal.get(). (also, we have 
ThreadLocal.set() - we can even change the value referenced; and 
InheritableThreadLocal, which by default copies over the Parent's value)

Alex

On 20/02/2014 09:24, Peter Levart wrote:
>
> On 02/19/2014 08:51 PM, Zhong Yu wrote:
>> Typically, a thread-local variable could be handed over to another
>> thread, with proper happens-before edge.
>
> What *is* a thread-local variable? Java does not have such thing. It 
> only has local variables, instance and static fields. If by 
> thread-local variable we mean a ThreadLocal object, then such 
> instances are usually meant to be shared by multiple threads. Contrary 
> to ThreadLocalRandom instance(s) which are better not (considering 
> current implementation and possible future changes). If by 
> thread-local variable we mean a state, associated with the pair 
> (ThreadLocal object, current thread) then the API itself makes it 
> impossible to share this state across threads. So the following 
> wording is a little confusing, I think:
>
>
> <p>Usages of this class should typically be of the form: {@code
> ThreadLocalRandom.current().nextX(...)} (where {@code X} is {@code
> Int}, {@code Long}, etc).  When all usages are of this form, it is
> never possible to accidentally share a {@code ThreadLocalRandom}
> across multiple threads. *As is the case for any thread-local **
> **variable, a {@code ThreadLocalRandom} should never be made **
> **accessible to other threads* by, for example, holding in a {@code
> static} field. A {@code ThreadLocalRandom} used by multiple threads
> need not (and typically will not) generate uniform random numbers.
>
>
> So I think it would be better to remove the "As is the case for any 
> thread-local
> variable, " part of the sentence. The rest makes perfect sense.
>
>
> Regards, Peter
>
>> The current impl of TLR
>> cannot do that due to its peculiar mechanism of initialization. So I
>> don't think it's enough to let users reason about it like a normal
>> ThreadLocal.
>>
>> Here's an example:
>>
>>      static ThreadLocalRandom random;
>>
>>      public static void main(String[] args) throws Exception
>>      {
>>          Thread t1 = new Thread( () ->
>>              random=ThreadLocalRandom.current()
>>          );
>>          t1.start();
>>          t1.join();
>>
>>          System.out.println( random.nextInt() ); // is the result random?
>>      }
>>
>> Zhong Yu
>>
>>
>> On Wed, Feb 19, 2014 at 7:11 AM, Doug Lea<dl at cs.oswego.edu>  wrote:
>>> On 02/18/2014 10:36 AM, Dr Heinz M. Kabutz wrote:
>>>> A little newsletter on this subject to warn my readers to never let their
>>>> ThreadLocalRandom instances escape.
>>>> http://www.javaspecialists.eu/archive/Issue218.html
>>> Thanks. Here's added javadoc that should someday be folded
>>> in. We still do not want to specify exactly what happens if
>>> you leak this or any other thread-local, since this might
>>> be subject to change over time in either TLR or ThreadLocal.
>>>
>>>     * tasks (for example, each a {@link ForkJoinTask}) use random numbers
>>>     * in parallel in thread pools.
>>>     *
>>> !  * <p>Usages of this class should typically be of the form:
>>> !  * {@code ThreadLocalRandom.current().nextX(...)} (where
>>> !  * {@code X} is {@code Int}, {@code Long}, etc).
>>> !  * When all usages are of this form, it is never possible to
>>> !  * accidently share a {@code ThreadLocalRandom} across multiple threads.
>>>     *
>>>     * <p>This class also provides additional commonly used bounded random
>>>     * generation methods.
>>> --- 33,47 ----
>>>     * tasks (for example, each a {@link ForkJoinTask}) use random numbers
>>>     * in parallel in thread pools.
>>>     *
>>> !  * <p>Usages of this class should typically be of the form: {@code
>>> !  * ThreadLocalRandom.current().nextX(...)} (where {@code X} is {@code
>>> !  * Int}, {@code Long}, etc).  When all usages are of this form, it is
>>> !  * never possible to accidentally share a {@code ThreadLocalRandom}
>>> !  * across multiple threads.  As is the case for any thread-local
>>> !  * variable, a {@code ThreadLocalRandom} should never be made
>>> !  * accessible to other threads by, for example, holding in a {@code
>>> !  * static} field. A {@code ThreadLocalRandom} used by multiple threads
>>> !  * need not (and typically will not) generate uniform random numbers.
>>>
>>>     *
>>>
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> Concurrency-interest at cs.oswego.edu
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20140221/e5dd50d5/attachment.html>


More information about the Concurrency-interest mailing list