That said, we are planning to support multiple threads using a worker model
(post-JDK8.) The underlying mechanism used to implement workers is shipping
with JDK8 (loadWithNewGlobal), so it will be possible to implement a similar
model yourself. You can run the following with 'jjs -scripting':
var Executors = java.util.concurrent.Executors;
var TimeUnit = java.util.concurrent.TimeUnit;
var ArrayList = java.util.ArrayList;
var script = <<EOD
i = 0;
i += 1;
shortly_later = new Date()/1000 + Math.random;
while( (new Date()/1000) < shortly_later) { Math.random() };
i += 1;
EOD
function addition() {
return loadWithNewGlobal({ name: "addition", script: script });
}
var executor = Executors.newCachedThreadPool();
var results = new ArrayList();
for(var i = 0; i < 50; i++) {
// Clarify Runnable versus Callable
results.add(executor["submit(java.util.concurrent.Callable)"](addition));
}
var miscalculations = 0;
for each (var result in results) {
var jsResult = result.get().intValue();
if (jsResult != 2) {
print("Incorrect result from js, expected 1 + 1 = 2, but got " +
jsResult);
miscalculations += 1;
}
}
executor.awaitTermination(1, TimeUnit.SECONDS);
executor.shutdownNow();
print("Overall: " + miscalculations + " wrong values for 1 + 1.");
Output:
Overall: 0 wrong values for 1 + 1.
Cheers,
-- Jim
On 2013-07-09, at 7:34 AM, Attila Szegedi <[email protected]> wrote:
> Hi,
>
> thanks for experimenting with Nashorn!
>
> As far as your example is concerned, Nashorn is not thread safe by design.
> Indeed, if you evaluate
>
> new NashornScriptEngineFactory().getParameter("THREADING")
>
> it'll return null, which means "the engine implementation is not thread safe,
> and cannot be used to execute scripts concurrently on multiple threads" --
> see
> <http://docs.oracle.com/javase/7/docs/api/javax/script/ScriptEngineFactory.html#getParameter(java.lang.String)>
>
> Nashorn library internals themselves are thread safe to the degree that we're
> using synchronized and concurrent data structures for various internal static
> caches et cetera, but JavaScript programs executing within a single engine
> instance are not thread safe.
>
> As I said, this is by design. ECMAScript 5.1 language specification doesn't
> define multithreading semantics for programs written in the language; they
> are inherently single threaded. If we were to make them thread safe, we'd be
> sacrificing single threaded performance for a behavior that falls outside of
> the specification. You can always create one script engine per thread using
> the same factory - that should work in a multithreaded scenario.
>
> Actually, in your above example, since the JavaScript program has no explicit
> guarding of concurrent access to variable `i` you seem like you would
> actually even expect to have an engine that has "THREAD-ISOLATED" as its
> threading model instead of the simpler "MULTITHREADED" - that' very rare in
> an engine, usually hard to implement efficiently (do you clone all of the
> data up front? do you implement a copy-on-write semantics?) , and is
> functionally simpler to just have a non-threadsafe engine and let the users
> manage their own thread isolation by creating one engine instance per thread.
>
> Cheers,
> Attila.
>
> On Jul 9, 2013, at 10:01 AM, Tobias Schlottke <[email protected]>
> wrote:
>
>>
>> Hi there,
>>
>> we're currently planning to switch our infrastructure from Rhino to Nashorn
>> but are experiencing some threading Issues that nobody addressed so far.
>> I tweeted with Jim Laskey and he kindly asked me to post it to this list.
>>
>> Example:
>>
>> https://gist.github.com/tobsch/5955518
>>
>> Could could you check this example and check if this really is a problem in
>> your eyes or if it is supposed to be this way?
>>
>> Best,
>>
>> Tobias
>>
>