2014-02-16 26 views
1

我正在研究可同時打開多個模型的擴展。模型可以動態地打開和關閉。模型以LiteWorkspace的形式打開,以便顯示小部件等。無論何時創建新的LiteWorkspace,它都會啓動JobThreadLifeguard。問題是關閉GUIWorkspaceLiteWorkspace的父級)不會終止其LifeguardJobThreadNetlogo擴展中的Juggling JobThreads和GUIWorkspaces

可能的解決方案:

  1. 理想的解決方案將是一個讓所有車型共享一個JobThread,因爲這將刪除線程數作爲一個能有多少款運行帽。這樣做也會有一定的性能優勢。這是否有可能?這個解決方案仍然需要能夠殺死Lifeguard

  2. 接下來將是能夠殺死線程當然。

  3. 作爲最後的手段,我們可以保留約GUIWorkspace s的池。當用戶關閉一個模型時,它會被扔回池中。然後,當用戶加載一個新模型並在池中有東西時,我們只需重新使用其中一個GUIWorkspace s。這將允許我們打開與2相同數量的模型。唯一的缺點是打開一個新模型(像文件菜單中的全新模式或其他)仍然不會殺死線程,所以有這個永久資源的行李掛在身邊。無論如何,出於性能原因,我們實際上可能必須建立一個池,但真正能夠在某個時刻釋放資源真的很不錯。

回答

1

解決方案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 = [email protected] 

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([email protected]) 

scala> Thread.getAllStackTraces().keySet.asScala.foreach(println) 
... 

(請注意,我在斯卡拉已經回答;轉換到Java留給讀者訪問一個內部類的外部實例反射的東西來自https://stackoverflow.com/a/763617/86485。)

,增加了代碼執行GUIWorkspace.dispose()在一個更清潔的方式將受到歡迎pull請求。

+0

完美的作品!謝謝! '這個$ 0'非常聰明。 –