<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Luminis Software Development &#187; concurrency</title>
	<atom:link href="http://lsd.luminis.nl/tag/concurrency/feed/" rel="self" type="application/rss+xml" />
	<link>http://lsd.luminis.nl</link>
	<description></description>
	<lastBuildDate>Mon, 19 Jul 2010 06:45:31 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>nl</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>ScheduledThreadPoolExecutor horribly broken</title>
		<link>http://lsd.luminis.nl/scheduledthreadpoolexecutor-horribly-broken/</link>
		<comments>http://lsd.luminis.nl/scheduledthreadpoolexecutor-horribly-broken/#comments</comments>
		<pubDate>Thu, 29 Mar 2007 16:03:17 +0000</pubDate>
		<dc:creator>Peter Doornbosch</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[mobility]]></category>
		<category><![CDATA[social]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[concurrency]]></category>

		<guid isPermaLink="false">http://lsd.luminis.net/?p=100</guid>
		<description><![CDATA[The Java concurrent package defines a powerful task-execution/thread-pooling architecture with a few interesting threadpool implementations. Unfortunately, the implementation of one of these is a bit sloppy, which leads to nasty surprises when you're actually trying to use it.]]></description>
			<content:encoded><![CDATA[<p>
A while ago, I considered using the Java 5 ThreadPoolExecutor class for executing<br />
remote calls asynchronuously. The application I was working on needs to perform remote<br />
calls on large numbers of devices, and as remote calls can take quite a while, you<br />
don&#8217;t want these remote calls to wait on each other. Moreover, as remote calls might fail,<br />
e.g. due to network problems, a retry mechanism was also needed. The<br />
ScheduledThreadPoolExecutor, a subclass of the ThreadPoolExecutor, additionally allows you to<br />
schedule a task at a certain delay, which offers a simple and elegant solution for the<br />
retry mechanism: when a remote call fails, I only had to re-schedule it with a<br />
proper (increasing) delay and the scheduler would take care of it.
</p>
<p>
Thanks to the fact the ThreadPoolExecutors provides an abstract method afterExecute()<br />
that is called after execution of the task, I didn&#8217;t have to pollute my task<br />
implementation with retry logic, but could clearly separate these concerns. In the<br />
afterExecute() method of the (subclassed) ScheduledThreadPoolExecutor, I could ask the<br />
task whether it had succeeded, and if not I could simply reschedule it. And all this<br />
just in a few lines of code:</p>
<pre>
void afterExecute(Runnable task, Throwable exception) {
     if ((RemoteCallerTask) task).failed()) {
         super.schedule(task, 10, TimeUnit.SECONDS);
     }
}
</pre>
<p>When I first tested it, I got a ClassCastExeception. My first guess was that it might<br />
have something to do with different class loaders, but when I ran it in a debugger it<br />
turned out to be something that realy surprised me: the Runnable task that was passed<br />
to this method was not my do-a-remote-call task that I had passed to the executor, but<br />
something of a completely different type<br />
(ScheduledThreadPoolExecutor$ScheduledFutureTask<V>).</p>
<p>
Maybe I misinterpreted the documentation? I went back to the ThreadPoolExecutor<br />
javadoc. It talked about &#8220;methods that are called before and after execution of each<br />
task&#8221;, and the parameter description claimed the Runnable parameter to be &#8220;the runnable<br />
that has completed&#8221;. This seemed to match my expectations: you execute a Runnable task<br />
and that is what is passed to afterExecute. That would be the only sensible definition<br />
of a after-execution hook, wouldn&#8217;t it? As the source code is the best documentation, I<br />
checked the ThreadPoolExecutor source, which confirmed what I was expecting: the task<br />
that is run is passed to the beforeExecute() and afterExecute() hooks.</p>
<p>
A little bit of studying on the ScheduledThreadPoolExecutor source revealed why I got a<br />
ClassCastExeception: it wraps the (user supplied) task in a ScheduledFutureTask object<br />
before passing it to the base class (that puts it in the task queue). One of the<br />
reasons why this wrapper is needed, is because the ScheduledThreadPoolExecutor uses a<br />
DelayQueue to store the tasks and elements of this queue must implemented Delayed<br />
(i.e. have a method that returns the delay). This type of queue sorts tasks based on<br />
the delay: shorter delay comes first. When taking an element from the queue, it blocks<br />
until the delay of the first task has passed. Using this type of queue makes the<br />
implementation of the ScheduledThreadPoolExecutor quite simple: it wraps the task in a<br />
wrapper that implements getDelay() and puts these wrappers in the queue.</p>
<p>
Although I can appreciate the beauty of using a DelayQueue in combination with a normal<br />
ThreadPoolExecutor, I don&#8217;t think it is the right solution. The point is that it breaks<br />
one of the fundamental principles of OO programming and that is that derived classes<br />
should respect the contract defined by the base class(es) (and or interfaces). The contract<br />
that the base class ThreadPoolExecutor defines, is that it will call the hook methods<br />
with your task as a parameter. ScheduledThreadPoolExecutor breaks this contract, as it<br />
does not adhere to what its base class has promised.</p>
<p>
This break of contract shouldn&#8217;t be taken lightly. It makes code that uses these<br />
executors fragile: if for some reason someone decides to use the other class as<br />
implementation of the general executor service, existing code might break. Put<br />
differently: in order to make your code robust, you would to have to take into account<br />
which executor implementation was chosen, at different points in your code. This<br />
violates principles of encapsulation and abstraction: code should never depend on<br />
implementation types, only on interfaces.</p>
<p>
I was pretty disappointed that even in the concurrency API, such fundamental<br />
mistakes can be found. Moreover, it appeared this is not the only break of contract, and that fixing this properly doesn&#8217;t seem to have any priority, but more on that later.</p>
]]></content:encoded>
			<wfw:commentRss>http://lsd.luminis.nl/scheduledthreadpoolexecutor-horribly-broken/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
