Closures not thread-safe?
João Paulo Varandas
joaovarandas at inpaas.com
Mon Feb 20 17:25:36 UTC 2017
Oops... You're right, my code evaluates the closure every time. Changing
'get' to 'initialValue' will achieve it's purpose, sorry about that.
It seems you have a nice use case over there, multi-threading is always
tricky and JavaScript adds another level of challenge, since sometimes
takes time to understand how the engine works at all(closures, lexical vs
dynamic scopes and global vars).
Anyway, good luck on your research and you're welcome, I'm glad that I
could help a little bit.
Cheers from Brazil!
Jp
2017-02-20 14:03 GMT-03:00 Frantzius, Jörg <Joerg.Frantzius at aperto.com>:
> Hi Joao,
>
> as you are overriding ThreadLocal.get(), the effect is that testJsFunction
> is simply eval()ed anew by every thread, so each thread creates its own
> closure. (I guess it’s never a good idea to override ThreadLocal.get()
> without calling super.get() at all …)
>
> But anyway, the real problem I have is probably mutation of a closure.
> That’s possible if the closure is over a mutable object, like a HashMap.
>
> Closure mutation works both in the same thread: https://gist.github.
> com/jfrantzius/0a40c963413bdeabb51ecb13a769a436#file-nashornclosuretest-
> java-L138
> As well as in another thread: https://gist.github.com/jfrantzius/
> 0a40c963413bdeabb51ecb13a769a436#file-nashornclosuretest-java-L166
>
> I guess my initial proposal of Nashorn performing some magical closure
> resolution with ThreadLocals is just bogus.
>
> I’ll go for dedicated global per thread, and as an optimization, I’ll pool
> them.
>
> Thanks for being helpful + cheers from Berlin,
> Jörg
>
>
> Am 20.02.2017 um 15:54 schrieb João Paulo Varandas <
> joaovarandas at inpaas.com>:
>
> @Test
> public void testClosureThreadSafety() throws ScriptException {
> String testJsFunction = (
> " (function outerFunction(currentThreadName) {\n" +
> " print(indx.incrementAndGet() + ' ' +
> java.lang.Thread.currentThread().toString() + ': closure data is ' +
> currentThreadName) \n" +
> " function innerFunction() {\n" +
> " return currentThreadName;\n" +
> " }\n" +
> " return innerFunction;\n" +
> " })(java.lang.Thread.currentThread().toString())\n");
>
> e.getBindings(ScriptContext.GLOBAL_SCOPE).put("indx", new
> AtomicInteger(0));
> ScriptObjectMirror jsFunction = (ScriptObjectMirror)
> e.eval(testJsFunction);
>
> String mainThreadName = Thread.currentThread().toString();
>
> ThreadLocal<ScriptObjectMirror> innerjs = new ThreadLocal<ScriptObjectMirror>()
> {
> @Override
> public ScriptObjectMirror get() {
> try {
> return (ScriptObjectMirror) e.eval(testJsFunction);
> } catch(Exception e) {
> throw new RuntimeException(e);
>
> }
> }
>
> };
>
> IntConsumer invokeAndTest = i -> {
> try {
> // my main closure is unchanged
> Assert.assertEquals(mainThreadName, jsFunction.call(jsFunction));
>
> // since I have a new closure for each thread ...
> final ScriptObjectMirror innerJsFunction = innerjs.get();
> final String currentThreadName = Thread.currentThread().
> toString();
> Assert.assertEquals(currentThreadName,
> innerJsFunction.call(innerJsFunction));
>
> } catch(Exception e) {
> throw new RuntimeException(e);
> }
>
> };
> IntStream.range(0, 10).parallel().forEach(invokeAndTest);
> }
>
>
> *---*
>
> *Dipl. Inf. Jörg von Frantzius, Technical Director*
>
> E-Mail joerg.frantzius at aperto.com
>
> Phone +49 30 283921-318 <+49%2030%20283921318>
> Fax +49 30 283921-29 <+49%2030%2028392129>
>
> Aperto GmbH – An IBM Company
> Chausseestraße 5, D-10115 Berlin
> http://www.aperto.com <http://www.aperto.de/>
> http://www.facebook.com/aperto
> https://www.xing.com/companies/apertoag
>
> HRB 77049 B, AG Berlin Charlottenburg
> Geschäftsführer: Dirk Buddensiek, Kai Großmann, Stephan Haagen, Daniel
> Simon
>
>
--
"Esta mensagem, incluindo seus anexos, pode conter informacoes
confidenciais e privilegiadas.
Se voce a recebeu por engano, solicitamos que a apague e avise o remetente
imediatamente.
Opinioes ou informacoes aqui contidas nao refletem necessariamente a
posicao oficial da Plusoft."
"Antes de imprimir, pense em sua responsabilidade e compromisso com o MEIO
AMBIENTE"
More information about the nashorn-dev
mailing list