我用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运行时?
答案 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()
方法告诉Matlab运行时运行打包的M脚本。
public void drawplot()
{
mcr.EvaluateFunction(0, "drawplot", new MWArray[]{});
}
如您所见,MWMCR类是运行M脚本的实际Matlab实例,它是一个静态对象。因此,无论实例化多少Plotter
或Class1
,都只有一个Matlab实例。多个mcr.EvaluateFunction
请求排队并一个接一个地执行。因此,如果没有生成两个MWMCR对象,理论上不可能同时运行多个Matlab脚本,这意味着您将需要多个Java程序集实例(经过实验确认)。
在您的情况下,所有数字都由MWMCR的相同实例绘制,WaitForFiguresToDie
或waitForFigures()
检查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();
}