java - 在 NetLogo 扩展中兼顾 JobThreads 和 GUIWorkspaces

标签 java multithreading api netlogo

我正在开发一个可以同时打开多个模型的扩展。模型可以动态打开和关闭。模型作为 LiteWorkspace 打开,以便显示小部件等。每当您创建新的 LiteWorkspace 时,它都会启动 JobThreadLifeguard。问题在于关闭 GUIWorkspace(LiteWorkspace 的父类)并不会终止其 Lifeguard 或 JobThread。

可能的解决方案:

  1. 理想的解决方案是让所有模型共享一个 JobThread,因为这将消除线程数量作为一个可以运行的模型数量的上限。这样做也会带来一定的性能优势。这有可能吗?此解决方案仍然需要能够杀死Lifeguard

  2. 接下来当然是能够杀死线程。

  3. 作为最后的手段,我们可以保留一个 GUIWorkspace 池。当用户关闭模型时,它会被扔回池中。然后,当用户加载新模型并且池中有东西时,我们只需重用其中一个 GUIWorkspace。这将允许我们打开与 2 相同数量的模型。唯一的缺点是打开一个新模型(例如从文件菜单或其他什么方式打开一个新模型)仍然不会杀死线程,因此存在永久资源包袱。实际上,出于性能原因,我们可能必须建立一个池,但如果能够在某个时候真正释放资源,那就太好了。

最佳答案

解决方案 1 不可行;每个工作区一个 JobThread 的假设深深嵌入到代码中。

要让 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)
...

(请注意,我已经在 Scala 中回答了;转换为 Java 留给了读者。用于访问内部类的外部实例的反射内容来自 https://stackoverflow.com/a/763617/86485 。)

欢迎以更简洁的方式添加实现 GUIWorkspace.dispose() 的代码的拉取请求。

关于java - 在 NetLogo 扩展中兼顾 JobThreads 和 GUIWorkspaces,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21815690/

相关文章:

C# 打印和线程

ruby - ActiveRecord Postgres 数据库未锁定 - 获取竞争条件

android - 我如何从 Google Fit API 获取步数?

asp.net - 我是否需要新的 PayPal API 来支持 .Net 服务器上的 TLS 1.2?

java - Web 应用程序安全架构

Java 枚举继承 : Is it possible to somehow extract the enums' toString() method to a common super class/enum?

java - 跨多个套接字的原子套接字消息

javascript - 从谷歌地图 api url 获取空 json

java - JAVA PriorityQueue 顺序不正确

java - 单击按钮时新 Intent 未启动