Login  Register

Re: ImageJ/FIJI crash on IJ.run(...)

Posted by dscho on Feb 18, 2014; 3:38pm
URL: http://imagej.273.s1.nabble.com/ImageJ-FIJI-crash-on-IJ-run-tp5006559p5006560.html

Hi Andrew,

On Tue, 18 Feb 2014, AJBell wrote:

> I have written a set of PlugIns for our image analysis which make use of
> Threading using the RunnableJob method. The scripts work as intended
> when launched from the ImageJ or Fiji plugings menu and from the plugins
> editor.  When I try to run the plugin from a button in a Frame, the
> program hangs.


I am glad that the program does not crash Fiji -- as suggested by the
mail's subject. Please be careful when describing software behavior (a
crash means that the program quits unexpectedly without giving the user a
chance to save her data, something quite different from a hang that does
not allow the user to interact with the program anymore).

> Thread t = new Thread(runnableJob, str_list[i]);
> t.start();
> t.join();

The "join()" is the problem.

Remember: your button press is detected and handled on the event dispatch
thread (EDT). It calls actionPerformed() eventually, still on the EDT.
Then you start a thread -- this thread will run parallel to the EDT.

But now "join()" is called -- waiting for the other thread to return. The
"join()" call is run *on the EDT*, blocking event dispatching until
further notice.

Now, that usually only makes the GUI unresponsive until the started thread
is done.

Except if that other thread tries to send an event itself -- which
imp.close() does: it needs to close the window, and that is done via
sending a WindowClosingEvent and then WindowCloseEvent.

Those messages are sent, and then the other thread *waits* until the
events are handled. Those events will need to be handled on the EDT,
though, and that thread is blocked.

Basically, the EDT is blocked waiting for the other thread while the other
thread says: no, you first. It's like Mid-West traffic: trying to be
polite and let the other go first, everybody just sits and waits.

A better way would be to design the program with less need to control: let
it spawn the threads and return. If something needs to be done in response
to those threads returning, it should be done at the end of those threads.

In general, it is a very good idea to spend as little time as possible
blocking the EDT. A good practice is to implement the real action as a
Runnable that the event handler will wrap in a Thread and start() it
("fire 'n forget" style).

Ciao,
Johannes

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html