Matlab编译器SDK绘图waitforFigures函数多个线程

时间:2017-04-16 14:42:04

标签: java matlab matlab-figure matlab-deployment matlab-compiler

我用matlab创建了一个简单的图,并用matlab编译器sdk创建了一个java jar。

我可以运行matlab创建的java函数并查看我的情节。

我想创建多个图并在单独的线程中启动该函数。 有用。但是,如果我启动我的java函数来创建多个图,第一个线程的waitforFigure()方法也在等待其他图也被关闭。因此,我的第一个线程不会继续阻塞,直到其他关闭后创建的图也将关闭。

我认为实例化一个Java类的Object,由Matlab编译器SDK生成一个新的Matlab编译器运行库?! 为什么waitforFigure方法也在等待其他图,如果它在单独的线程上运行?

这是我创建的RunAlgorithm类的函数runFunction。 runFunction方法实例化Matlab Compiler SDK创建的Class,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类的Function。 我实例化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-Plot。

编辑:

如果我运行我的应用程序两次。 waitforFigure方法只是等待一个应用程序生成的线程。 这意味着,matlab运行时与应用程序一起运行一次,与我创建的线程无关?

所以Class1实例化每次都没有启动新的matlab运行时?

编辑: 如果我将我的matlab代码编译为Singleton,那么我的绘图将被刷新。这意味着,我的Class1对象的实例正在启动一个新的matlab运行时?

1 个答案:

答案 0 :(得分:2)

我查看了你的问题并尝试在我的机器上创建一个Matlab jar。但是,由于某种原因,创建一个jar文件失败了,所以我为.net应用程序创建了一个dll。无论如何,基本原则应该是相似的。

以下是生成的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()方法告诉M​​atlab运行时运行打包的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();
}