我最近一直在和这部剧合作!框架和Nashorn,试图呈现Redux应用程序。最初,我在ThreadPoolExecutor中实现了多个Nashorn引擎,并在运行引擎时使用了futures。eval()
。性能很差,我想是因为我使用的是高I/O和阻塞未来。
在更加熟悉游戏之后!还有他们的异步/promise模式,我试图用一个脚本引擎重新开始;每https://stackoverflow.com/a/30159424/5956783,脚本引擎本身是线程安全的,但绑定不是。以下是整个课程:
package services;
import akka.actor.ActorSystem;
import play.libs.F;
import scala.concurrent.ExecutionContext;
import java.io.FileReader;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.script.*;
@Singleton
public class NashornEngine extends JSEngineAbstract {
private NashornThread engine;
private final ActorSystem actorSystem;
protected class NashornThread {
private ScriptEngine engine;
private final ExecutionContext executionContext = actorSystem.dispatchers().lookup("js-engine-executor");
private CompiledScript compiledScript;
public NashornThread() {
try {
String dir = System.getProperty("user.dir");
this.engine = new ScriptEngineManager(null).getEngineByName("nashorn");
this.compiledScript = ((Compilable) this.engine).compile(new FileReader(dir + "/public/javascripts/bundle.js"));
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public ScriptEngine getEngine() {
return engine;
}
public F.Promise<String> getContent(String path, String globalCode) {
return F.Promise.promise(() -> this.executeMethod(path, globalCode), this.executionContext);
}
private String executeMethod(String path, String json) throws ScriptException {
Bindings newBinding = engine.createBindings();
try {
this.compiledScript.eval(newBinding);
getEngine().setBindings(newBinding, ScriptContext.ENGINE_SCOPE);
getEngine().eval("var global = this;");
getEngine().eval("var console = {log: print, error: print, warn: print};");
String result = getEngine().eval("App.renderApp('" + path + "', " + json + ")").toString();
return result;
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
}
@Inject
public NashornEngine(ActorSystem actorSystem) {
this.actorSystem = actorSystem;
this.engine = new NashornThread();
}
@Override
public F.Promise<String> getContent(String path, String globalCode) {
try {
F.Promise<String> result = engine.getContent(path, globalCode);
return result.map((String r) -> r);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
我的JavaScript应用程序导出一个
App
对象,方法renderApp(路径,状态)
可见。这实际上确实有效,但只有16次(是的,总是16次)。从迭代17开始,我得到以下异常和随附的堆栈跟踪:
java.lang.ClassCastException: jdk.nashorn.internal.objects.NativeRegExpExecResult cannot be cast to jdk.nashorn.internal.objects.NativeArray
at jdk.nashorn.internal.objects.NativeArray.getContinuousArrayDataCCE(NativeArray.java:1900)
at jdk.nashorn.internal.objects.NativeArray.popObject(NativeArray.java:937)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:660)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:228)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.internal.scripts.Script$Recompilation$23589$782286AA$\^eval\_.L:22918$L:22920$matchPattern(<eval>:23049)
at jdk.nashorn.internal.scripts.Script$Recompilation$23588$816752AAAAAA$\^eval\_.L:24077$L:24079$matchRouteDeep(<eval>:24168)
at jdk.nashorn.internal.scripts.Script$Recompilation$23587$820262DAA$\^eval\_.L:24077$L:24079$matchRoutes$L:24252$L:24253(<eval>:24254)
at jdk.nashorn.internal.scripts.Script$Recompilation$23586$809060$\^eval\_.L:23848$loopAsync$next(<eval>:23869)
at jdk.nashorn.internal.scripts.Script$Recompilation$23584$808906AAA$\^eval\_.L:23848$loopAsync(<eval>:23875)
at jdk.nashorn.internal.scripts.Script$Recompilation$23583$820189$\^eval\_.L:24077$L:24079$matchRoutes$L:24252(<eval>:24253)
at jdk.nashorn.internal.scripts.Script$Recompilation$23582$819862AAA$\^eval\_.L:24077$L:24079$matchRoutes(<eval>:24252)
at jdk.nashorn.internal.scripts.Script$Recompilation$23580$789440AA$\^eval\_.L:23151$L:23153$useRoutes$L:23209$match(<eval>:23239)
at jdk.nashorn.internal.scripts.Script$Recompilation$23518$847004AA$\^eval\_.L:25026$L:25028$match(<eval>:25084)
at jdk.nashorn.internal.scripts.Script$Recompilation$23468$3872AA$\^eval\_.L:53$renderApp(<eval>:147)
at jdk.nashorn.internal.scripts.Script$23467$\^eval\_.:program(<eval>:1)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:640)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:228)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:446)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:403)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:399)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
at services.NashornEngine$NashornThread.executeMethod(NashornEngine.java:62)
at services.NashornEngine$NashornThread.lambda$getContent$0(NashornEngine.java:48)
at play.core.j.FPromiseHelper$$anonfun$promise$2.apply(FPromiseHelper.scala:36)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
我的印象是,用编译后的脚本创建一个新的绑定将被视为引擎的新功能,但事实似乎并非如此。我到底做错了什么?
我尝试使用
Invocable
调用App
对象上的方法,但这没有任何区别。
编辑我在一台具有超线程的8核机器上,因此这可以解释在失败的第17次尝试之前的16次成功尝试。此外,我已将
刽子手方法
方法更新如下:
private String executeMethod(String path, String json) throws ScriptException {
Bindings newBinding = engine.createBindings();
try {
this.compiledScript.eval(newBinding);
getEngine().eval("var global = this;", newBinding);
getEngine().eval("var console = {log: print, error: print, warn: print};", newBinding);
Object app = getEngine().eval("App", newBinding);
Invocable invEngine = (Invocable) getEngine();
String result = invEngine.invokeMethod(app, "renderApp", path, json).toString();
// String result = getEngine().eval("App.renderApp('" + path + "', " + json + ")", newBinding).toString();
return result;
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
不幸的是,您在Nashorn中遇到了一个错误。好消息是它已经被修复,并且该修复在当前的早期访问版本中可用。
更新到最新版本的Nashorn或Java 1.8u76修复了这个问题。
下面我分享了我的代码,我试图使用线程安全的Nashorn作为脚本引擎来评估简单的数学公式。公式将类似于“a*b/2”,其中a 我需要知道这种方法是否有助于使Nashorn线程在这个用例中安全。我在Attila的回答中读到,我们可以在线程之间共享脚本引擎对象,因为它们是线程安全的。 对于bindings和eval,因为我们正在为每次执行evaluate创建新线程,每个线程都有自己的bindings对
如果以下代码在多线程应用程序中可以工作,您可以帮助我吗。 这是我的Java脚本,将由Nashorn评估 这就是我创建脚本引擎的方式 在使用Testng进行测试时,此操作不会出现任何错误 测试结果1-请注意,有些数据是重复的 但是,如果我添加"并行=true"到@DataProvider我的脚本开始失败 测试结果2-请注意,重复一些数据,以表明相同的参考编号可能在测试过程中随机失败 有人可以确认我是
问题内容: 我正在编写一个将HashMap返回给用户的应用程序。用户将获得对此MAP的引用。在后端,我将运行一些线程来更新Map。 到目前为止我做了什么? 我已经使所有后端线程都共享一个公用通道来更新MAP。因此,在后端,我确信并发写入操作不会成为问题。 我遇到的问题 如果用户尝试更新MAP并同时在后端更新MAP->并发写入操作问题。 如果使用尝试从MAP读取某些内容,同时MAP正在后端更新->并
我们想在servlet中使用Nashorn。这个想法是使用ScriptEngine的单例实例,该实例在每次请求时都被重用。在每次请求时都会创建一个新的Engineering Scope绑定,并使用该绑定运行评估。然后清除绑定。没有共享对象被传递给绑定(只有servlet中的请求/响应对象)。 在servlet中,ScriptEngine的单例实例可能会在不同的线程中同时评估,这会正常工作还是会遇到
条款16: 让const成员函数线程安全 如果我们在数学领域中工作,我们就会发现用一个类表示多项式是很方便的。在这个类中,使用一个函数来计算多项式的根是很有用的。也就是多项式的值为零的时候。这样的一个函数它不会更改多项式。所以,它自然被声明为const函数。 class Polynomial { public: using RootsType = // 数据结构保存
我想在我的Android应用程序中处理位图——位图可能很大,所以我使用多线程来执行更快的操作。以下是我的代码(Runnable child的一部分): 当我只使用池中的一个线程时,一切正常。不幸的是,当我使用的线程数等于处理器的内核数(在我的设备中为4)时,结果如下(对于灰度过滤器): 有时看起来像: bitmap.get像素(...)不起作用,因为输出中有黑线 bitmap.set像素(...)