JEP draft: Scope Locals
Peter Levart
peter.levart at gmail.com
Wed May 19 16:55:28 UTC 2021
On 15/05/2021 19:50, Peter Levart wrote:
> Another question: Suppose there are two inheritable ScopeLocal
> variables with bound values in scope (A and B) when I take a snapshot:
>
> var snapshot = ScopeLocal.snapshot();
>
> now I pass that snapshot to a thread which does the following:
>
> ScopeLocal
> .where(C, "value for C")
> .run(() -> {
> System.out.printf("A:%s B:%s C:%s\n", A.isBound(),
> B.isBound(), C.isBound());
> ScopeLocal.runWithSnapshot(() -> {
> System.out.printf("A:%s B:%s C:%s\n", A.isBound(),
> B.isBound(), C.isBound());
> }, snapshot);
> System.out.printf("A:%s B:%s C:%s\n", A.isBound(),
> B.isBound(), C.isBound());
> });
>
> What would this code print?
>
> ...in other words, does runWithSnapshot replace the whole set of bound
> values or does it merge it with existing set?
...let me answer this myself, after checking current implementation. The
answer is: "It depends on whether C is an inheritable ScopeLocal or
non-inheritable". If I understand the code correctly there are two
independent sets of bindings: inheritable and non-inheritable.
snapshot() retrieves the current inheritable set and runWithSnapshot()
replaces current inheriatable set with the snapshot for the execution of
given Runnable and afterwards swaps previous inheritable set back.
So if C is inheritable, the output would be:
A:false B:false C:true
A:true B:true C:false
A:false B:false C:true
...but if C is non-inheritable, the output would be:
A:false B:false C:true
A:true B:true C:true
A:false B:false C:true
This seems consistent. In other words, non-inheritable bindings are
never transferred from thread to thread automatically or by
snapshot/runWithSnapshot. I can see that snapshot/runWithSnapshot was
meant as a mechanism to "simulate" inheritance of bindings when
execution is transferred from one thread to another which is not a newly
started child thread.
Regards, Peter
Peter
More information about the core-libs-dev
mailing list