3

我用matlab創建了一個簡單的繪圖,並用matlab編譯器sdk創建了一個java jar。Matlab編譯器SDK繪圖waitforFigures函數多線程

我可以運行由matlab創建的java函數並查看我的圖。

我想創建多個圖並在單獨的線程中啓動該功能。 它的工作原理。但是,如果我啓動我的java函數來創建多個圖,第一個線程的waitforFigure()方法正在等待其他圖也被關閉。所以我的第一個線程不會繼續並阻塞,直到在關閉之後創建的其他地塊。

我想實例化一個Java類的對象,由Matlab編譯器生成的SDK創建一個新的Matlab編譯器運行時?!。 爲什麼waitforFigure方法也等待其他圖,如果它在單獨的線程上運行?

這裏是我創建的RunAlgorithm類的函數runFunction。 runFunction方法實例化Matlab編譯器SDK創建的類Class1。它是類的默認名稱。 thePlot函數是在Matlab運行時運行的matlab代碼並繪製我的數據。

void runFunction(MWNumericArray x1, MWNumericArray y1, MWNumericArray z1) throws MWException { 


Class1 thePlot = new Class1; 

    /* Number of points to plot */ 
    try { 


     /* Plot data */ 
    thePlot.runAlgorithm(x1, y1, z1); 
    thePlot.waitForFigures(); 

    } 

    catch (Exception e) { 
     System.out.println("Exception: " + e.toString()); 
    } 

    finally { 
     /* Free native resources */ 
     MWArray.disposeArray(x1); 
     MWArray.disposeArray(y1); 
     MWArray.disposeArray(z1); 
     if (thePlot != null) 
      thePlot.dispose(); 
    } 
} 

這裏我簡單的線程如何執行包含我的Matlab類的函數。 我實例化RunAlgorithm類,從文件中讀取數據,並將它轉換爲MWNumericArray傳遞給runFunction方法。 在我的runFunction方法中有waitforFigures方法阻塞。

Thread t1=new Thread() { 
      public void run() { 


     RunAlgorithm a = new RunAlgorithm(); 
     RunAlgorithm.Measurements n = null; 

     try { 
      n= a.readFile(selectecValue); 
      System.out.println("File REad"); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     try { 

      a.runFunction(n.mX, n.mY, n.mZ); 
     } catch (MWException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     } 
      }; 
      t1.start(); 

基本上我讀一個CSV文件,解析到MWnumericArray我的數據,並把它傳遞給RunAlgorithm類。該類內部使用runFunction創建Class1對象,並使用Matlab運行時繪製Matlab-圖。

編輯:

如果我運行我的應用程序兩次。 waitforFigure方法只是等待一個應用程序生成的線程。 這意味着,matlab運行時與應用程序運行一次,獨立於我創建的線程?

因此,Class1實例並不是每次啓動一個新的matlab運行時?

編輯: 如果我編譯我的matlab代碼爲單身人士,然後我的情節刷新。那意味着,我的Class1對象的實例是啓動一個新的matlab運行時?

+0

我只是想知道我是否已經解決了您的問題。 – Anthony

+0

不完全。在我看來,像一個黑客而不是一個正確的解決方案 – Khan

回答

2

我看了一下你的問題,並試圖在我的機器上創建一個Matlab jar。但是,由於某種原因,創建一個jar文件失敗了,所以我創建了一個dll for .net應用程序。無論如何,基本原則應該是相似的。

這裏是在生成的C#代碼中發現的構造的一個單元:

private static MWMCR mcr= null; 
static Plotter() 
{ 
    if (MWMCR.MCRAppInitialized) 
    { 
    try 
    { 
     /* a lot of codes here but deleted to make what is important stands out */ 
     mcr= new MWMCR("", 
        ctfFilePath, embeddedCtfStream, true); 
    } 
    catch(Exception ex) { //some code here } 
    } 
} 

public Plotter() 
{ 
    if(ex_ != null) 
    { 
    throw ex_; 
    } 
} 

而且drawplot()方法它告訴Matlab的運行時運行該包裝M-腳本。

public void drawplot() 
{ 
    mcr.EvaluateFunction(0, "drawplot", new MWArray[]{}); 
} 

正如你所看到的,MWMCR類是運行M-腳本實際Matlab的實例,它是一個靜態的對象。因此,無論實例化多少個PlotterClass1,都只有一個Matlab實例。多個mcr.EvaluateFunction請求排隊並一個接一個地執行。因此,如果沒有生成兩個MWMCR對象,理論上同時運行多個Matlab腳本是不可能的,這意味着您將需要Java程序集的多個實例(實驗確認)。


在你的情況下,所有的數字都被MWMCR的同一個實例,並WaitForFiguresToDiewaitForFigures()檢查由MWMCR繪製任何未關閉的數據繪製的。

public void WaitForFiguresToDie() 
{ 
    mcr.WaitForFiguresToDie(); 
} 

一個解決方案,我可以向你求婚的,包括你的jar包空Matlab代碼(EmptyCode())。然後在您的java代碼中執行類似以下內容:

void runFunction() 
{ 
    Class1 thePlot = new Class1; 
    Thread t1=new Thread() { 
     public void run() { 
      Class1 thePlot = new Class1; 
      thePlot.waitForFigures(); 
      } 
    } 
    Thread t2=new Thread() { 
     public void run() { 
      Class1 thePlot = new Class1; 
      thePlot.waitForFigures(); 
      } 
    } 
    thePlot.waitForFigures(); 
    t1.start(); 
    t2.start(); 

    //your java code 

    thePlot.EmptyCode(); 
    thePlot.waitForFigures(); 
}