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(); 
}