Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么可以';我是否可以同时从Java执行不同的Matlab函数?_Java_Matlab_Servlets_Matlab Compiler_Matlab Java - Fatal编程技术网

为什么可以';我是否可以同时从Java执行不同的Matlab函数?

为什么可以';我是否可以同时从Java执行不同的Matlab函数?,java,matlab,servlets,matlab-compiler,matlab-java,Java,Matlab,Servlets,Matlab Compiler,Matlab Java,我有两个Java servlet:DataFetcherServlet和UploaderServlet。这两个servlet都调用了两个不同的Java方法,它们通过JNI调用相应的Matlab函数,每个方法都被编译成一个单独的JavaJAR文件作为库使用。该应用程序由AJAX提供支持,以创建类似桌面的感觉。对于UploaderServlet,用户可以将excel文件上载到此servlet,然后将解析的数据传递给Java方法,该方法随后调用编译的Matlab函数生成并保存大量图像(目前超过5000

我有两个Java servlet:
DataFetcherServlet
UploaderServlet
。这两个servlet都调用了两个不同的Java方法,它们通过JNI调用相应的Matlab函数,每个方法都被编译成一个单独的JavaJAR文件作为库使用。该应用程序由AJAX提供支持,以创建类似桌面的感觉。对于
UploaderServlet
,用户可以将excel文件上载到此servlet,然后将解析的数据传递给Java方法,该方法随后调用编译的Matlab函数生成并保存大量图像(目前超过5000张图像),因为这将花费大量时间,我使用
ExecutorService
在后台执行它。但是,在图像生成部分完成之前,还会调用另一个编译的Matlab函数的
DataFetcherServlet
发送的新请求被阻止。我不知道为什么它会阻止新的请求,即使请求被发送到不同的servlet

DataFetcherServlet.java

public class DataFetcherServlet extends HttpServlet {

    @Inject
    private CdfReader reader; // An EJB to get a data array from Matlab

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        try {
            String filePath = "path/to/file";
            Object[] result = reader.read(filePath); // reader.read() is just a wrapper around the method in the jar file mentioned above that actually calls the matlab function to return an array of number
            MWNumericArray array = (MWNumericArray)result[0] // This will block while the other Matlab function is generating the images.
            .
            .
            .
        } catch (MWException ex) {
            Logger.getLogger(DataFetcherServlet.class.getName()).log(Level.SEVERE, null, ex);
    }
}
public class UploaderServlet extends HttpServlet {
    @Inject
    private ExcelIonImageGenerator generator; // An EJB to call Matlab to generate the images

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        try {
            String dir = "path/to/parent/directory";
            Path excel = Paths.get(dir+ "excel", part.getSubmittedFileName()); // Path to where the uploaded excel file is stored
            if (!Files.exists(excel))
                Files.copy(part.getInputStream(), excel);
            // ExcelExtractor is a helper class to parse the excel file.
            Double[][] ranges = ExcelExtractor.extractSheet(WorkbookFactory.create(excel.toFile()));
            // This will call a Java library method which in turns call the Matlab function
            // to generate the images (over 5000 in this case)
            // See the code for this method below.
            generator.generate(dir+ "images" + File.separator, ranges);
        } catch (MWException | InvalidFormatException ex) {
            Logger.getLogger(UploaderServlet.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
UploaderServlet.java

public class DataFetcherServlet extends HttpServlet {

    @Inject
    private CdfReader reader; // An EJB to get a data array from Matlab

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        try {
            String filePath = "path/to/file";
            Object[] result = reader.read(filePath); // reader.read() is just a wrapper around the method in the jar file mentioned above that actually calls the matlab function to return an array of number
            MWNumericArray array = (MWNumericArray)result[0] // This will block while the other Matlab function is generating the images.
            .
            .
            .
        } catch (MWException ex) {
            Logger.getLogger(DataFetcherServlet.class.getName()).log(Level.SEVERE, null, ex);
    }
}
public class UploaderServlet extends HttpServlet {
    @Inject
    private ExcelIonImageGenerator generator; // An EJB to call Matlab to generate the images

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        try {
            String dir = "path/to/parent/directory";
            Path excel = Paths.get(dir+ "excel", part.getSubmittedFileName()); // Path to where the uploaded excel file is stored
            if (!Files.exists(excel))
                Files.copy(part.getInputStream(), excel);
            // ExcelExtractor is a helper class to parse the excel file.
            Double[][] ranges = ExcelExtractor.extractSheet(WorkbookFactory.create(excel.toFile()));
            // This will call a Java library method which in turns call the Matlab function
            // to generate the images (over 5000 in this case)
            // See the code for this method below.
            generator.generate(dir+ "images" + File.separator, ranges);
        } catch (MWException | InvalidFormatException ex) {
            Logger.getLogger(UploaderServlet.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
ExcelIonImageGenerator.java

import com.mathworks.toolbox.javabuilder.*; // Matlab SDK needed to integrate with Java
import java.util.concurrent.*;
import java.util.logging.*;
import javax.annotation.PreDestroy;
import javax.ejb.Stateless;
import save_ion_image_for_all_ranges_in_spreadsheet.Class1; // The jar file which contains code to call Matlab code through JNI

@Stateless
public class ExcelIonImageGenerator {
    private final Class1 clazz1;
    private ExecutorService pool;

    public ExcelIonImageGenerator() throws MWException {
        clazz1 = new Class1();
        pool = Executors.newFixedThreadPool(1);
    }

    public void generate(String path, Double[][] ranges) throws MWException {
        // Submit this task to the ExecutorService so it can be processed
        // in a different thread than the caller thread
        pool.submit(() -> generateHelper(path, ranges, clazz1), 1);
    }

    private void generateHelper(String path, Double[][] ranges, Class1 clazz) {
        try {
            // This method was generated by Matlab tool, it calls the native
            // Matlab code through JNI, and it will block any request that will call
            // other Matlab functions until it finishes.
            clazz.save_ion_image_for_all_ranges_in_spreadsheet(path, ranges);
        } catch (MWException ex) {
            Logger.getLogger(ExcelIonImageGenerator.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

您有三种选择:

  • 启动调用Matlab的Java应用程序的多个进程。来自单个进程的调用使用具有进程范围锁的相同MCR,但是来自不同进程的调用将在单独的MCR计算引擎上运行
  • 使用,这基本上方便了多个MCR的使用。这是一个需要单独许可和安装的工具包
  • 您不必限制自己运行MCR/编译代码,除非您有非常具体的性能问题。实际上,您可以在服务器上安装Matlab本身,从同一个Java进程启动多个实例(headless等),并通过或新的官员与它们通信

  • MatlabCentral上有一个非常好的例子,详细解释了MCR的这些限制。

    因为主要的Matlab执行发生在单个线程上?可能是。我们在服务器上安装了matlab运行时。但是,当某些matlab函数为某些用户执行时,每个用户都会被阻止是的,它会阻止其他用户。您必须启动多个Matlab实例(例如,每个用户一个实例)并适当地发送命令,或者使用类似于“您知道如何启动多个Matlab实例吗?如何启动第一个实例?”?你必须以某种方式启动并连接到它。就这么做几次?非常感谢。第一个选项是不可能的,因为我们正在运行一个web应用程序,因此为smame用户创建这么多进程将杀死该应用程序,因为进程占用大量内存,我们不知道有多少用户将同时使用该应用程序。第二种选择,我们可以研究。方案3是目前最可行的方案。我真诚地感谢你的帮助