Java 在NetLogo扩展中处理作业线程和GUI工作区
我正在开发一个可以同时打开多个模型的扩展。模型可以动态打开和关闭。模型作为Java 在NetLogo扩展中处理作业线程和GUI工作区,java,multithreading,api,netlogo,Java,Multithreading,Api,Netlogo,我正在开发一个可以同时打开多个模型的扩展。模型可以动态打开和关闭。模型作为litespace打开,以便显示小部件等。每当你创建一个新的LiteWorkspace,它就会启动一个JobThread和Lifeguard。问题在于,关闭GUIWorkspace(LiteWorkspace的父类)并不会杀死它的救生员或作业线程 可能的解决办法: 理想的解决方案是让所有模型共享一个JobThread,因为这将消除线程数作为一个模型可以运行的上限。这样做也有一定的性能优势。这有可能吗?此解决方案仍然需要能够
litespace
打开,以便显示小部件等。每当你创建一个新的LiteWorkspace
,它就会启动一个JobThread
和Lifeguard
。问题在于,关闭GUIWorkspace
(LiteWorkspace
的父类)并不会杀死它的救生员
或作业线程
可能的解决办法:
JobThread
,因为这将消除线程数作为一个模型可以运行的上限。这样做也有一定的性能优势。这有可能吗?此解决方案仍然需要能够杀死救生员
GUIWorkspace
s周围保留一个池。当用户关闭一个模型时,它会被抛出回池中。然后,当用户加载一个新模型并且池中有东西时,我们只需重用其中一个GUIWorkspace
s。这将允许我们打开与2相同数量的模型。唯一的缺点是打开一个新模型(比如全新的,从“文件”菜单或其他什么)仍然不会杀死线程,所以这是一个永久性的资源包袱。实际上,出于性能原因,我们可能不得不建立一个池,但如果能够在某个时候真正释放资源,那就太好了解决方案1不可行;每个工作区一个作业线程的假设深深地嵌入到代码中 要使JobThread消亡,这应该足够了:
workspace.jobManager.haltPrimary()
workspace.jobManager.die()
要使GUIWorkspace.Lifeguard线程死亡,我们只需要对其调用interrupt()
,但即使只是获取对它的引用也不是那么容易。这是一份记录,显示了一次成功的尝试:
/Applications/NetLogo 5.0.5 % scala29 -Yrepl-sync -classpath NetLogo.jar
Welcome to Scala version 2.9.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51).
scala> val applet = new org.nlogo.lite.Applet
applet: org.nlogo.lite.Applet = ...
scala> applet.init()
...
scala> val ws = applet.panel.workspace: org.nlogo.window.GUIWorkspace
ws: org.nlogo.window.GUIWorkspace = org.nlogo.lite.LiteWorkspace@69cafecd
scala> import collection.JavaConverters._
import collection.JavaConverters._
scala> Thread.getAllStackTraces().keySet.asScala.foreach(println)
Thread[JobThread,4,main]
Thread[Lifeguard,6,main]
...
scala> ws.jobManager.haltPrimary()
scala> ws.jobManager.die()
scala> import util.Try
import util.Try
scala> for {
thread <- Thread.getAllStackTraces().keySet.asScala
if thread.getName == "Lifeguard"
outer = Try{ val field = thread.getClass.getDeclaredField("this$0")
field.setAccessible(true)
field.get(thread) }
if outer.toOption == Some(ws)
} {
thread.interrupt()
thread.join()
}
Success(org.nlogo.lite.LiteWorkspace@69cafecd)
scala> Thread.getAllStackTraces().keySet.asScala.foreach(println)
...
/Applications/NetLogo 5.0.5%scala29-Yrepl sync-classpath NetLogo.jar
欢迎使用Scala版本2.9.3(Java热点(TM)64位服务器虚拟机,Java 1.7.0_51)。
scala>val applet=new org.nlogo.lite.applet
applet:org.nlogo.lite.applet=。。。
scala>applet.init()
...
scala>val ws=applet.panel.workspace:org.nlogo.window.GUIWorkspace
ws:org.nlogo.window.GUIWorkspace=org.nlogo.lite。LiteWorkspace@69cafecd
scala>import collection.JavaConverters_
导入collection.JavaConverters_
scala>Thread.getAllStackTraces().keySet.asScala.foreach(println)
线程[作业线程,4,主线程]
线程[救生员,6,主]
...
scala>ws.jobManager.haltPrimary()
scala>ws.jobManager.die()
scala>import-util.Try
导入util.Try
scala>用于{
thread thread.getAllStackTraces().keySet.asScala.foreach(println)
...
(注意,我已经用Scala回答了这个问题;到Java的转换留给读者。用于访问内部类的外部实例的反射内容来自于。)
一个以更简洁的方式添加代码实现
GUIWorkspace.dispose()
的请求将是受欢迎的。工作得很好!谢谢!这个$0的非常聪明。