[ImageJ-devel] [fiji-devel] Imglib2: using threadpools in core algorithms

Tobias Pietzsch pietzsch at mpi-cbg.de
Thu Dec 5 20:52:16 CST 2013


On Dec 5, 2013, at 11:56 PM, Curtis Rueden <ctrueden at wisc.edu> wrote:

> Hi again,
> 
> > * Encapsulates internal dependencies such as java.util.concurrent
> > (e.g., Avian doesn't have that package!).
> 
> And Android / J2ME doesn't have java.util.concurrent either. I am interested in porting ImageJ2 to Android (which would necessitate a port of ImgLib2 to Android). The more "weird" Java packages we use, the more involved it will be to refactor those usages out later to make such a thing possible. The "swappability" of SJC services will obviate the need to do it in some cases.

On a closer look, ThreadService uses java.util.concurrent.Callable and import java.util.concurrent.Future.
It also extends java.util.concurrent.ThreadFactory. So the Android/AVIAN argument is not really valid.

To reiterate my previous question why not extend the ExecutorService interface instead?
One answer I could give to that myself is that we do not need/want the full ExecutorService, e.g., an imglib algorithm should not be allowed to shutdown() the ExecutorService.
On the other hand, we do not need/want the full ThreadService, e.g. using newThread() from the ThreadFactory is not wanted.

So could we maybe extract the part of ExecutorService that we are interested in (invokeAll, invokeAny, and submit variants) into a new interface and make ThreadService extend that?
This would still not allow us to pass a standard ExecutorService into imglib algorithms but a ThreadService. I could live with it.
The question then is whether this should live in imglib, in scijava-common, or somewhere else. I hesitate making scijava-common a dependency of imglib. I know just having scijava-common as a dependency does not force me to use the application container but still… Making imglib a dependency of scijava-common is not a good idea either.
Hmm...

best regards,
Tobias

> 
> Regards,
> Curtis
> 
> 
> On Thu, Dec 5, 2013 at 4:48 PM, Curtis Rueden <ctrueden at wisc.edu> wrote:
> Hi Tobias,
> 
> > Curtis, could you elaborate on why you prefer scijava-common
> > ThreadService? I just had a look and, as an interface, I cannot see
> > what would make it preferable to ExecutorService. For me a point in
> > favour of ExecutorService is that it is in the JDK. What additional
> > value would ThreadService provide?
> 
> For me, the fact that we control the ThreadService API contract is a point in its favor. If we need to add some functionality, we cannot add it to ExecutorService, because it is part of core Java. But the SciJava Common API can adapt to our needs.
> 
> > Would it be an option to let ThreadService extends ExecutorService?
> 
> As a rule of thumb, I prefer composition to inheritance [1]. The SciJava Common ThreadService *has* an ExecutorService internally. Right now, that is not exposed in the API contract, but we could do so (i.e., a "setExecutor" method). That would also solve Lee's single-threaded use case without requiring him to override the DefaultThreadService implementation itself.
> 
> > Correct me if I'm wrong, but I thought the same was the idea about
> > ExecutorService…
> 
> Yes. ExecutorService is an interface, so if the ImgLib2 API contract uses that interface, it is true that callers can pass whatever kind of ExecutorService they want. And that is a form of dependency injection.
> 
> The SciJava Common approach uses SezPoz to discover plugins (including services) and organize them by priority. If a ThreadService is found on the classpath with higher priority than the DefaultThreadService, it will take precedence for any SciJava application context that needs a ThreadService.
> 
> Advantages of ExecutorService:
> * Avoids dependency on SciJava Common, and potential overhead of SJC application context.
> * Easy to override threading behavior on a case-by-case basis (i.e., pass different ExecutorServices to different algorithms).
> 
> Advantages of ThreadService:
> * Can improve the API as needed.
> * Encapsulates internal dependencies such as java.util.concurrent (e.g., Avian doesn't have that package!).
> * Easy to globally override threading behavior for an entire application context.
> 
> There are surely other reasons to go one way or the other, but that's all that's coming out of my brain at the moment.
> 
> Regards,
> Curtis
> 
> [1] https://en.wikipedia.org/wiki/Composition_over_inheritance
> 
> 
> 
> On Thu, Dec 5, 2013 at 4:27 PM, Tobias Pietzsch <pietzsch at mpi-cbg.de> wrote:
> 
> On Dec 5, 2013, at 10:32 PM, Johannes Schindelin <Johannes.Schindelin at gmx.de> wrote:
> 
> > Hi Tobi,
> >
> > On Thu, 5 Dec 2013, Tobias Pietzsch wrote:
> >
> >> Curtis, could you elaborate on why you prefer scijava-common ThreadService?
> >
> > Very easy: scijava-common's ThreadService can be overridden by your own
> > implementation. Such as a ThreadService backed by KNIME's own…
> 
> Correct me if I'm wrong, but I thought the same was the idea about ExecutorService…
> best regards,
> Tobias
> 
> >
> > Remember, not everybody starts everything on a single-user desktop
> > machine, in an Oracle JVM launched from within Eclipse with a Swing/AWT
> > user interface ;-)
> >
> > Ciao,
> > Dscho
> 
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://imagej.net/pipermail/imagej-devel/attachments/20131206/2bb32aba/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://imagej.net/pipermail/imagej-devel/attachments/20131206/2bb32aba/attachment.pgp>


More information about the ImageJ-devel mailing list