Skip to main content

The importance of encapsulation and explicit interface constraints

A couple days ago, a co-worker and I stumbled upon an unintended constraint in some of the thread pool abstractions in the system we're working on.  These threading abstractions leaned too heavily on the underlying ThreadPoolExecutor in Java for their semantics and did a poor job of hiding these from client code.  Specifically, this class has corePoolSize and maximumPoolSize settings.  The former is often misconstrued as a minimum pool size, which it's not; it's actually the maximum number of threads that should be created automatically before the work queue reaches its maximum size.

However, when this abstraction is well-known at a low level and then translated to a higher-level abstraction, that distinction may be lost in translation.  When treated as a minimum size, it fails to meet expectations in a rather significant way.  For instance, if you have the core size configured to be 1, the max size configured to be 20, and are using an unbounded work queue for the thread pool, the number of threads created to perform work will never exceed one!

There's adequate evidence that this behavior is confusing and somewhat non-intuitive, at least for some developers.  I think having an explicit minimum setting might have helped alleviate this confusion, even if most developers would probably never have chosen something other than zero for it.  The documentation explains how it functions, but developers sometimes assume they understand something when it looks intuitive.  If there's a danger of misinterpreting something that looks otherwise intuitive, additional details in the interface that draw attention to these tripping points are valuable.

Also, this distinction was clearly known by those initially developing the components that interacts with this class, but as that abstraction was translated faithfully to a higher level (without encapsulation and introducing a separation of abstractions) it lead to unexpected behavior and confusion.

Comments

Popular posts from this blog

Java command line app with Spring and Gradle

Many Java developers have had to build a command line app for one reason or another over the years, and there are many(!) ways to do it.  There are a bevy of command line libraries, some people roll their own when they get to this point (which is one reason why there are so many command line libraries!), and others just pull in the arguments simply and directly, eschewing a library. However, writing a tool, a developer should just focus on the meat of the problem rather than having to worry about the enabling functionality that allows it to work.  The Spring Framework very much supports this approach to development with its inversion of control (IoC) container and a myriad of other features. To support that approach for command line applications, the spring-cmdline library provides a bridge between the Spring framework and the JOpt Simple command line library. This tutorial will show how to leverage the spring-cmdline library to stand up a very simple command line ap...

manifest classpath + taglib jars + Tomcat = FAIL

I found an interesting side-effect of using manifest classpaths in our application jar files as it applies to taglib jar dependencies and embedded Tomcat 6. ·          Manifest classpaths do not appear to be expanded in the URLClassLoaders that load the jars with the manifests, so only the jar file referenced directly on the classpath are included in its URLs. The taglib search mechanism in Tomcat 6 (haven't checked Tomcat 7 to see if there's a difference) only walks the classpath looking for URLClassLoaders, looking at the underlying JAR URLs. Thus, if the taglib jar is referenced only as a dependency in the manifest of the main jar file and is not specifically on the classpath, it will not be spotted and use of that taglib by the JSP engine will throw an exception. This problem won’t actually show up in tests as IDE environments and builds generally include all the jar files in the classpath, so this one will bite you at runtime. ...