Matlab Compiler SDK plot waitforFigures function multiple threads - java

I have created a simple plot with matlab and created a java jar with matlab compiler sdk.
I can run the java function created by matlab and see my plot.
I wanted to create multiple plots and started the function in separate threads.
It works. But if i start my java function for creating multiple plots, the waitforFigure() method of the first thread is waiting for the other plots to be closed too. So my first thread does not continue and blocks till the other plots who are created after it also are closed.
I thought instantiating a Object of the Java class, produced by the Matlab compiler SDK creates a new Matlab compiler runtime?!.
Why is the waitforFigure method waiting for the other plots too, if it is run on seperate thread?
Here is my function runFunction of the RunAlgorithm class i created.
The runFunction methods instantiates the Matlab Compiler SDK created Class, Class1. Its the default name of the class. The thePlot function is the matlab code running in the Matlab runtime and plots my data.
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();
}
}
Here my simple thread how it executes the Function containing my Matlab class.
I instantiate the RunAlgorithm class, read data from file, and pass it converted to MWNumericArray to the runFunction method.
In my runFunction method there is the waitforFigures method blocking.
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();
Basically i read a csv File, parse my Data in to MWnumericArray, and pass it to the RunAlgorithm class. That Class internally creates the Class1 Object with the runFunction and plots my Matlab- Plot with Matlab runtime.
EDIT:
If i run my application twice. The waitforFigure method is just waiting for the threads generated by one application.
That would mean, the matlab runtime is run once with the application, independent from the threads i created?
So the Class1 instantiation is not starting a new matlab runtime everytime?
EDIT:
If i compile my matlab code as Singleton,then my plot is refreshed. That would mean, the instatiation of my Class1 Object is starting a new matlab runtime ?

I had a look into your problem and tried to create a Matlab jar on my machine. However, for some reason, creating a jar file failed, so instead I created a dll for .net application. The underlying principle should be similar anyway.
Here is a snap of the constructors found in the generated C# code:
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_;
}
}
And the drawplot() method which tells the Matlab runtime to run the packaged M-script.
public void drawplot()
{
mcr.EvaluateFunction(0, "drawplot", new MWArray[]{});
}
As you can see, the MWMCR class is the actual Matlab instance that runs the M-script and it is a static object. Therefore, no matter how many Plotter or Class1 is instantiated, there is only one Matlab instance. Multiple mcr.EvaluateFunction requests are queued and executed one after one. Therefore, theoretically running multiple Matlab scripts simultaneously is not possible without having two MWMCR objects generated, which means you will need multiple instances of your java assembly (experimentally confirmed).
In your case, all figures are plotted by the same instance of MWMCR, and WaitForFiguresToDie or waitForFigures() checks for any unclosed figures plotted by MWMCR.
public void WaitForFiguresToDie()
{
mcr.WaitForFiguresToDie();
}
A solution I can propose to you is to include an empty Matlab code (EmptyCode()) in your jar package. Then implement something similar to the following in your java code:
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();
}

Related

Is it safe to restart Java after uncaught exception with another Java program?

I am working on a project that has to process external signals passed as an input to Java program. The signals can be corrupted (i.e. we don't have much control of the input) which may lead to processing errors (such as DivisionByZeroException).
What my team wants is that each time uncaught exception is thrown, which causes the Java program to terminate, SOME CODE should just restart the Java program from scratch.
Therefore, my main question is: Any danger of writing SOME CODE in the following way?
MY SOLUTION (SOME CODE will be another Java class):
Suppose our Java program is implemented as a method M of class C that gets called once and ideally should run forever.
I firstly make class C implement Runnable interface.
I then override run method as:
class C implements Runnable {
#Override
public void run() {
this.M();
}
public void M() {
// Code for main method to be called ONCE and ideally run FOREVER
....
}
}
Finally, I create a wrapper (called Recovery class) around class C to restart C.M() each time an exception is thrown:
class Recovery {
final Object lock = new Object();
void runAndRecover(final Runnable runnable) { // Will pass an instance of C
while (true) {
// Synchronising to make sure that only one instance
// of runnable input is running at the time.
synchronized(lock) {
try {
runnable.run();
// Ideally the process should run forever
// (no termination),
// and the code of THIS FILE will be blocked HERE
// with the runnable RUNNING (which is what we want).
} catch (Exception exception) {
// If the process was interrupted
// by uncaught exception,
// we will restart it.
lock.notifyAll();
}
}
}
}
}
What I hope is that we could run the system as follows:
public static void main(final String[] args) {
C c = new C();
Recovery recovery = new Recovery();
recovery.runAndRecover(c);
// My hope is that code gets blocked HERE and runs REGARDLESS
// of anything happening inside c. Can I make such assumption?
}
A side question: if this approach is not safe, I could then write a shell script to restart the Java program each time exception is thrown. What would be a simple shell loop to repeatedly execute command sudo java /path/to/Program? Is writing a shell script safer?

Can I do 'global Shared Object' in Java?

I have two CLASS(each has a thread), and I want to create a queue shared between them. So one class could write some bytes to the queue, and the other can read from the SAME queue.
I tried static, and here are my codes:
public class ShareQueueTest {
public static final BlockingQueue<byte[]> memshare= new ArrayBlockingQueue<>(1000);
public static void main(String[] args){
Thread a = new Thread(){public void run(){
for(;;){
try {
memshare.put(new byte[20]);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(memshare.size());
}
}};
a.start();
}
}
And the other class is simple read from this queue.
public class ShareQueueTest2 {
public static void main(String[] args){
Thread a = new Thread(){public void run(){
for(;;){
System.out.println(ShareQueueTest.memshare.size());
}
}};
a.start();
}
}
I run it. Though one thread is putting bytes in this queue, the other is still saying the queue is empty all the time. So clearly they are referred to the different things.
ALL the thing happens in local machine.
As this question is simplified from a network scenario, so for some reason, I don't want another class to manipulate those two threads, they are blind to each other. Perhaps the only thing they know for each other is that each thread running on the same local machine, plus, they know the port numbers of the other. Under such condition, I need some methodologies to create a data structure which both of them can 'see'.
I also think of using memory address. Like one class get the memory address of the object, and the other get the object from the address and cast it to the correct data structure. Is it possible in java?
Any help will be appreciated!
Since both of your classes have a main method, it appears that you may be running these two classes in separate processes (instances of the JVM)
If you call ShareQueueTest2.main(...) from ShareQueueTest.main, it should work
If you call the two classes separately, it would spawn two separate JVMs which are two separate processes. The thread cannot communicate across processes via a shared queue.
You need to start both the threads from the same code as the other answers point out. Then you can access the shared variables and see the changes done by one thread get reflected in the other thread.
Try this :
public class ShareQueueTest {
public static final BlockingQueue<byte[]> memshare= new ArrayBlockingQueue<>(1000);
public static void subMain(String[] args){
Thread a = new Thread(){public void run(){
for(;;){
try {
memshare.put(new byte[20]);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(memshare.size());
}
}};
a.start();
}
}
public class ShareQueueTest2 {
public static void subMain(String[] args){
Thread a = new Thread(){public void run(){
for(;;){
System.out.println(ShareQueueTest.memshare.size());
}
}};
a.start();
}
}
public class Launch
{
public static void main( String[] args)
{
ShareQueueTest1.subMain(args);
ShareQueueTest2.subMain(args);
}
}

Thread does not start in a Swing application

I am working on a relatively simple DB manager, that takes in a number of files, parses and catalogs the information in a particular fashion. I also wrote a simple GUI in Swing for this purpose. In order to speed up the process I want to implement multithreading to the parallelizable parts of the execution in order to speed up the program.
The below code sits in a class called FDBCreatePanel, a custom JPanel, that sits in a FDBManagerFrame which accommodates the main method.
private void dbCreateActionButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dbCreateActionButtonActionPerformed
jfc = new JFileChooser();
jfc.setVisible(true);
jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int returnVal = jfc.showSaveDialog(null);
((FDBManagerFrame) SwingUtilities.getRoot(this)).startProcessAnimation();
if(returnVal == JFileChooser.APPROVE_OPTION) {
new SwingWorker<Void,Void>(){
#Override
protected Void doInBackground() throws Exception {
File dir = jfc.getSelectedFile();
DbManager dbm = new DbManager(dir, dbNameField.getText());
try{
dbm.doTimeConsumingStuff();
} catch (SQLException e){
// errorhandling
}
#Override
protected void done() {
((FDBManagerFrame) SwingUtilities.getRoot(FDBCreatePanel.this)).endProcessAnimation();
}
}.execute();
}
}
The time consuming method in DbManager class leads to (among others) the following bits of code in the ParserType1 class:
private void init() {
try {
this.reader = new LineNumberReader(new FileReader(this.datfile));
Thread t = new Thread(new Runnable(){
#Override
public void run() {
Entry e;
while((e = parseNextEntry()) != null)
queue.offer(e);
}
}, "t1-parser-thread");
t.run();
} catch (FileNotFoundException e) {
// error handling
}
}
I do not see any t1-parser-thread(s) in JVisualVM when I monitor the execution of my program. It appears as if my code executes entirely on a single thread, ignoring the initiation of new threads. Am I missing something with respect to threading and Swing?
You're calling run() on the newly created Thread object in ParserType1.init(). That doesn't start a new thread - it just execute's the thread's run() method in the existing thread. You should be calling start() instead.
Fundamentally I think it was a mistake for Thread to implement Runnable at all - the distinction between "this is the code that should be executed" (Runnable) and "this is the way I'm going to execute it" (Thread) has been unfortunately blurred. The fact that Thread can also compose a Runnable makes it even worse.
Runnable runnable = new Runnable() { ... };
Thread thread = new Thread(runnable) {
// Override run here...
};
Unless your overridden run method calls super.run(), the Runnable passed into the constructor is ignored. Crazy stuff. Thread should (IMO) be final, not implement Runnable, and force you to provide a Runnable at construction. It's far too late to change now, unfortunately :(
Basically, you should never be calling run() on a Thread. At least, I can't remember the last time I saw that without it being a bug.
As Jon Pointed out you want to call the start() method to actually spawn a new Thread which will call the run method of your inline Runnable. If you just call run it is like you called any other method and it will execute in the same Thread.
}, "t1-parser-thread");
t.start();
http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html

Is it possible to draw graphs using JavaFX in a normal Java application?

I want to draw some graphs of statistics gathered during a simulation I coded in Java. I decided to try JavaFX, as it has some great graphing abilities. However, as I've never used it before, I'm not sure if it's even possible to add JavaFX capabilities to a project that wasn't set up to do this initially.
I've added the javafx library to my project, and copy pasted the JavaFX tutorial on line graphs at http://docs.oracle.com/javafx/2/charts/line-chart.htm (without the main function) to test if the graphs display properly.
They don't, however. I call the graph in my runsimulation function (which is called from a SwingWorker thread) with
LineChartSample.launch(new String());
and after running the program and not seeing any graph, I added a println after the call and noticed that the program doesn't ever reach it; i.e. it terminates on the call to LineChartSample.
Am I doing something wrong? Is what I'm trying even possible?
EDIT: A quick summary of what that part of the code looks like:
A JButton in class InputGUI calls
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
new AnswerWorker().execute();
}
public class AnswerWorker extends SwingWorker<Void, Integer> {
protected Void doInBackground() throws Exception
{
AMEC.runsimulation();
return null;
}
protected void done()
{
try {
JOptionPane.showMessageDialog(InputGUI.this, AMEC.unsuccesfulpercentage + "% of iterations had trucks that had to sleep over");
AMEC.unsuccesfulpercentage = 0;
}
catch (Exception e)
{
e.printStackTrace();
}
}
And AMEC.runsimulation calls
public static void runsimulation() throws IOException, InterruptedException {
...
LineChartSample.launch(new String());
}
I get the JDialogBox that AnswerWorker throws when it's done, but no graph, and whenever I test for a println after my LineChartSample.launch call, it never gets reached.
try
public static void runsimulation() throws IOException, InterruptedException {
...
LineChartSample.launch(LineChartSample.class, "");
}
for more information:
http://docs.oracle.com/javafx/2/api/javafx/application/Application.html#launch%28java.lang.String...%29
be aware that you shouldn't actually do it like this, because you can't call this code more than once in your applications lifetime. Instead, you should extract the code from the LineChartSample that builds the scene graph and use a JFXPanel to embed the scene graph into your swing application.

Run a .java file using ProcessBuilder

I'm a novice programmer working in Eclipse on Windows XP, and I need to get multiple processes running (this is going to be a simulation of a multi-computer system). My initial hackup used multiple threads to multiple classes, but now I'm trying to replace the threads with processes.
From my reading, I've gleaned that ProcessBuilder is the way to go. I have tried many many versions of the input you see below, but cannot for the life of me figure out how to properly use it. I am trying to run the .java files I previously created as classes (which I have modified). I eventually just made a dummy test.java to make sure my process is working properly - its only function is to print that it ran.
My code for the two files are below. Am I using ProcessBuilder correctly? Is this the correct way to read the output of my subprocess? Any help would be much appreciated.
David
Edit: The solution is to declare ProcessBuilder("java.exe","-cp","bin","Broker.test");
primary process
package Control;
import java.io.*;
import java.lang.*;
public class runSPARmatch {
/**
* #param args
*/
public static void main(String args[]) {
try {
ProcessBuilder broker = new ProcessBuilder("javac.exe","test.java","src\\Broker\\");
Process runBroker = broker.start();
Reader reader = new InputStreamReader(runBroker.getInputStream());
int ch;
while((ch = reader.read())!= -1)
System.out.println((char)ch);
reader.close();
runBroker.waitFor();
System.out.println("Program complete");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
subprocess
package Broker;
public class test {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("This works");
}
}
You are calling the java compiler on the .java file, this will not run the class. What you probably want to do is running java.exe on your .class file. (ie something like "java.exe -cp ./bin Broker.test", assuming your class files are in ./bin)

Categories

Resources