두 개의 Java Servlets (DataFetcherServlet
및 UploaderServlet
)이 있습니다. 두 서블릿은 서로 다른 두 가지 자바 메소드를 호출하며, 각각의 자바 메소드는 JNI를 통해 해당 Matlab 함수를 호출하며 각 함수는 별도의 Java jar 파일로 컴파일되어 라이브러리로 사용됩니다. 응용 프로그램은 AJAX에 의해 바탕 화면 느낌을 생성합니다. UploaderServlet
의 경우, 사용자는이 서블릿에 엑셀 파일을 업로드 할 수 있습니다. 파싱 된 데이터는 Java 메소드로 전달되어 컴파일 된 Matlab 함수를 호출하여 이미지 (현재 5000 개가 넘는 이미지)를 생성하고 저장합니다. 시간이 많이 걸리는 경우 배경에서 실행하려면 ExecutorService
을 사용합니다. 그러나 DataFetcherServlet
을 보낸 새로운 요청은 이미지 생성 부분이 완료 될 때까지 차단 된 다른 컴파일 된 Matlab 함수를 호출합니다. 요청이 다른 서블릿으로 보내 졌음에도 불구하고 왜 새 요청을 차단하는지 알 수 없습니다.다른 Matlab 함수를 동시에 Java에서 실행할 수없는 이유는 무엇입니까?
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);
}
}
UploaderServlet.java
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 실행은 단일 스레드에서 발생하기 때문에? –
가능할 수 있습니다. 우리는 서버에 matlab 런타임을 설치했습니다. 그러나 일부 사용자가 일부 matlab 기능을 실행하는 동안 모든 사용자가 차단됩니다 – Dummy
예, 다른 사용자를 차단합니다. Matlab 인스턴스를 여러 개 (예 : 사용자 당 하나씩) 실행하고 명령을 적절하게 라우트하거나 [Matlab Production Server] (http://uk.mathworks.com/products/matlab-production-server/)와 같은 것을 사용해야합니다. –