<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D08FRnw4eyp7ImA9WhdXFEk.&quot;"><id>tag:blogger.com,1999:blog-653496027060462681</id><updated>2011-08-27T14:50:17.233+03:00</updated><category term="RRWL" /><category term="iterator" /><category term="aspectj" /><category term="list" /><category term="java" /><category term="concurrency" /><category term="spring" /><category term="interruption" /><title>[blog() ! X || X &lt;- Brain]</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://artemv12.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://artemv12.blogspot.com/" /><author><name>artemv12</name><uri>http://www.blogger.com/profile/13734695625317422045</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_pidCk5ODrPM/Sytr85MrQfI/AAAAAAAABEc/8CaZxo7GP6E/S220/ZEa6z.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>11</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/blogspot/artemv12" /><feedburner:info uri="blogspot/artemv12" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DU4CSHs5fyp7ImA9Wx9UGUk.&quot;"><id>tag:blogger.com,1999:blog-653496027060462681.post-8863067882989817684</id><published>2011-02-17T15:01:00.011+02:00</published><updated>2011-02-17T15:06:09.527+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-17T15:06:09.527+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="iterator" /><category scheme="http://www.blogger.com/atom/ns#" term="list" /><title>Doing smart stuff with List and Iterator</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Many times the objects in a list must be converted into some others objects, i.e. when&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;we need to get a different list with converted objects. It's trivial from first glance:&lt;/span&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;List&lt;message&gt; toJmsMessageList(List&lt;mymessage&gt; originalMyMessageList) {
 List&lt;message&gt; resultList = new ArrayList&lt;message&gt;(originalMyMessageList.size());
 for(MyMessage msg : originalMyMessageList) {
  resultList.add(Converter.convert(msg));
 }
 return resultList;
}
&lt;/message&gt;&lt;/message&gt;&lt;/mymessage&gt;&lt;/message&gt;&lt;/pre&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Nothing wrong with the above code, except: &lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;1. it's boring and verbose&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;2. it creates new list&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;3. it iterates over original list&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;4. problems might occur when original list is ORM proxy list obtained as a result &lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;of sql query, so operations such as size() on it - would cause problems such as retrieval of whole result set' content into memory&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;So, here's solution. What I actually want - convert list' stuff into list of another stuff, I would like to have something like: &lt;/span&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;List resultList = ListFactory.createList(originalList, callback);
&lt;/pre&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;So whenever resultList iteration being called I want to have already converted stuff in it! So, here's what I came to: &lt;/span&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;&lt;t&gt; List&lt;t&gt; createList(final Iterator originalIterator, final Callable&lt;t&gt; c) {
 // iteration handler for custom list implementation
 InvocationHandler invocationHandler = new InvocationHandler() {
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) {
   if (method.getName().equals("iterator")) {
    return new Iterator&lt;t&gt;() {
     @Override
     public boolean hasNext() {
      return originalIterator.hasNext();
     }

     @Override
     public T next() {
      try {
       // call 'custom behavior'
       return c.call();
      } catch (Exception e) {
       log.error("Error during user defined operation on originalIterator", e);
       throw new RuntimeException(e);
      }
     }

     @Override
     public void remove() {
      // 'remove' isn't supported
      throw new UnsupportedOperationException();
     }
    };
   }
   // everthying other than iteration isn't supported
   throw new UnsupportedOperationException();
  }
 };
 return (List) Proxy.newProxyInstance(
     Thread.currentThread().getClass().getClassLoader(),
     new Class[] {List.class}, 
     invocationHandler);
}
&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/pre&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Here's possible use cases:&lt;/span&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;return ListFactory.createList(originalListIterator, new Callable&lt;messageentity&gt;() {
 private int fetchedNum = 0; // the number of fetched objects
 @Override
 public MessageEntity call() {
  if (++fetchedNum % fetchSize == 0) {
   // remove fetched MessageEntity entities from iternal jpa's identity map
   // when number of fetched objects reaches 'fetchedNum'
   getEntityManager().clear();
  }
  // don't forget call iterator.next()
  return originalListIterator.next();
 }
});
&lt;/messageentity&gt;&lt;/pre&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;or&lt;/span&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;ListFactory.createList(messagesIterator, new Callable&lt;entry&gt;() {
 @Override
 public Entry call() {
  try {
   return toEntry(messagesIterator.next());
  } catch (Exception e) {
   log.error("Error occured while converting list of jms messages", e);
   throw new RuntimeException(e);
  }
 }
});
&lt;/entry&gt;&lt;/pre&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Thanks for reading.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/653496027060462681-8863067882989817684?l=artemv12.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/artemv12/~4/KwD52SabySg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://artemv12.blogspot.com/feeds/8863067882989817684/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://artemv12.blogspot.com/2011/02/doing-smart-stuff-with-list-and.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/8863067882989817684?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/8863067882989817684?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/artemv12/~3/KwD52SabySg/doing-smart-stuff-with-list-and.html" title="Doing smart stuff with List and Iterator" /><author><name>artemv12</name><uri>http://www.blogger.com/profile/13734695625317422045</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_pidCk5ODrPM/Sytr85MrQfI/AAAAAAAABEc/8CaZxo7GP6E/S220/ZEa6z.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://artemv12.blogspot.com/2011/02/doing-smart-stuff-with-list-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIMQX0-eyp7ImA9Wx5aGU4.&quot;"><id>tag:blogger.com,1999:blog-653496027060462681.post-8234830156898209592</id><published>2010-11-03T21:46:00.021+02:00</published><updated>2010-11-16T21:43:00.353+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-16T21:43:00.353+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="concurrency" /><title>Language that matters</title><content type="html">&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Preface&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;The purpose of this article is to help my friends to better understand,&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;why&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; they should spend their time learning Erlang/Scala, and&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;even functional programming, instead of Java.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;This's "time-friendly" explanation of the "actor-based" concurrency,&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;it's not something that requires from you to have the iq &amp;gt;= 150.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Author found himself in a very bad shape when he had started getting understanding&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;"actor-based" concurrency from wikipedia or from original article. So, if you're smart enough to understand everything from the original sources and think that this article is a naive piece of shit&amp;nbsp;then getta fuck out from here.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Begin&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Last year I was in Chernigov, visited the good friend of mine, and we had a kind of disput around concurrency.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;That was a time when I finished learning utillities from java.util.concurrent, researching concurrent collections and the rest concurrent crap,&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;and finally I became amazed of what Java offers! (still 're)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Then my friend said one thing, that backup me in reality, he said that there're tasks which couldn't be implemented concurrently, and you can't do any with this,&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;it's simply impossible, say factorial: f(x) = x * f(x-1).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;From the school you know that you should wait until next call will return result, and next call should wait ... etc. Even if you transform f(x) into more&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;"parallel-friendly" form: x*(x-1)*f(x-2), you still wouldn't be able to calculate x*(x-1) in thread1 and f(x-2) in thread2.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Seems like obvious thing - but it's undoable!&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Why? 'cause of Java' architecure doesn't allow this and C/C++ arch. doesn't allow this, and Python, Pascal doesn't allow this and whatever&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;imperative language you take - it will fail with such a primitive task.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Last weekend I spent some time on Erlang presentation. Why Erlang? Because it's buzzword nowadays - "concurrent-oriented functional language",&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;"next-mainstream language", "facebook and twitter" use it, and etc. etc. etc. So, like a regular code monkey which could be easily "picked up" by marketing noice, I decided to look into it.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;But, you know, unfortunately I have an average IQ, so, I didn't get from the first try(and from the second, and from the third)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;several principal topics:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;why it's functional language?!&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;what "message oriented language" certainly means, in details what's that?!&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;what're lightweight process, and how it's possible that Erlang maintains thousands of them?! (Ok, I know that cpu has cores and&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;num_of_cores = num_of_threads(aka OS threads), I know what's OS processes mean, but WTF "leightweight process" does mean?!)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;language' creators assert that erlang-program will run x- times faster on x- core machine! WTF?! How?! What they can do with factorial?!&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Does it matter 10 or 2 cores, for f(8) you still should wait for f(6), for f(6) you should wait for f(4) and etc.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;After three hours I found the answer on last question, and then on the rest three. No math equations, no theorems - just logical thinking.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;It's simple&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Say, we want calculate f(5) concurrenctly, having 2 CPUs(cores), right now don't bother &lt;b&gt;how&lt;/b&gt;. See the picture:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_pidCk5ODrPM/TNGyMxO-ZiI/AAAAAAAABeU/Pe9zy8hdrPo/s1600/f.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;img border="0" height="640" src="http://4.bp.blogspot.com/_pidCk5ODrPM/TNGyMxO-ZiI/AAAAAAAABeU/Pe9zy8hdrPo/s640/f.PNG" width="504" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;You can see that "lightweight process" is just a function. But how they connect to each other&lt;b&gt;(*)&lt;/b&gt;, how they return results to each other&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;in a way that makes program run very fast?! In Java, for example, functions "connect" to each other through stack of&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;execution and in C/C++ too, and in Python, and in Pascal..&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; font-size: small;"&gt;Let me guide you through the last question&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; font-size: small;"&gt;&lt;b&gt;(*)&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; font-size: small;"&gt;. Write down f(5) in this way:&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;P1#cpu2 = P2#cpu1 * (P3#cpu1 = P4#cpu1 * P5#cpu2)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Pi#CPUj &amp;nbsp; &amp;nbsp; - i-th leightweight process on CPUj&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;i &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - in [1, many]&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;j &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - num of cores&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;Ok, but still, how this excels imperative style ?! Why f(5) should run faster if add one more core?!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;The answer: Pi executes its work and doesn't wait for completion of Pi+1, each Pi executes independently!&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;It's done through non-blocking IO, non-blocking queues and message passing! Each process have a non-blocking queue from&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;which it reads messages, it's same as:&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif; font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="prettyprint"&gt;class process {
    ConcurrentLinkedQueue queue;
    void receive() {
        for(;;) {
            if (queue.get() != null) {
                // hey! what's up?!
            }
        }
    }
}
&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;OS scheduler allocates thread and cpu-time for each Pi to execute, and it's ok if it can't do anything usefull! For example if P3#cpu1 gets time to&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;execute(read 'being assigned to OS thread') it will find that there's nothing to do 'cause P4#cpu1 and P5#cpu2 didn't return&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;results, so what?! - yield OS thread and let the other processes get a chance to work!&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif; font-size: 3px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;The most attracting part of all this - you get grid/cloud/network computing almost&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;out of the box:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;P1#(127.0.0.1) = P2#(243.88.33.11) * (P3#(10.10.0.6) = P4#(77.55.99.33) * P5#(14.133.15.16))&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif; font-size: 3px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;Hope this article will help you in understanding the "state-of-things" when you decide start learning Erlang or Scala and encourage you to get more about the topic.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;Thanks for your time!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;b&gt;References&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Lambda_calculus"&gt;http://en.wikipedia.org/wiki/Lambda_calculus&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Actor_(computer_science)"&gt;http://en.wikipedia.org/wiki/Actor_(computer_science)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Erlang_(programming_language)"&gt;http://en.wikipedia.org/wiki/Erlang_(programming_language)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/653496027060462681-8234830156898209592?l=artemv12.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/artemv12/~4/aWCWtduBTYs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://artemv12.blogspot.com/feeds/8234830156898209592/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://artemv12.blogspot.com/2010/11/language-that-matters.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/8234830156898209592?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/8234830156898209592?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/artemv12/~3/aWCWtduBTYs/language-that-matters.html" title="Language that matters" /><author><name>artemv12</name><uri>http://www.blogger.com/profile/13734695625317422045</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_pidCk5ODrPM/Sytr85MrQfI/AAAAAAAABEc/8CaZxo7GP6E/S220/ZEa6z.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_pidCk5ODrPM/TNGyMxO-ZiI/AAAAAAAABeU/Pe9zy8hdrPo/s72-c/f.PNG" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://artemv12.blogspot.com/2010/11/language-that-matters.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08BQ3k8cCp7ImA9Wx5aGU4.&quot;"><id>tag:blogger.com,1999:blog-653496027060462681.post-5669290754721258351</id><published>2010-03-22T09:22:00.052+02:00</published><updated>2010-11-16T22:37:32.778+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-16T22:37:32.778+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="spring" /><title>Using thread-bound HttpServletRequest exposed by Spring to bring DI on view tier</title><content type="html">&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Im saying about how to obtain request object in a web application at arbitrary point of your web tier code. Sometimes it can be very useful, especially&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; when this object hidden in abstract layers.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Spring provides a couple of very useful classes for doing this. But at first let me explain the problem.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;See, sometimes you can have legacy application that wasnt designed for dependency injection, testability, being POJO and etc. For example, it means that somewhere in view tier code, in struts' actions you have:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="prettyprint"&gt;...
MyActionForm execute(Form inForm, ActionMapping mapping, Session s) {
    ...
    AccountManager accountManager
             = locator.getSessionEjb(AccountManagerHome.JNDI_NAME, s.getEjbProviderUrl());
    ...
}
...&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;In other words, you have a ubiquitous EJB lookup code which works using http session 'cause it holds some critical info, e.g. providerUrl like in example above. And this code makes your actions:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;not unit-testable;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; being hard to switch from one biz impl. to another, e.g. from EJB to POJO;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; contains RemoteException handling code (even if you have defined RE handling somewhere in superclass you actually need to call this superclass' handling method)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; So, here's solution' primary points:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;lookup code moves to spring context xml in the from of FactoryBean implementations;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; add &lt;a href="http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/web/context/request/RequestContextListener.html"&gt;RequestContextListener&lt;/a&gt; as listener to web.xm; this class binds request to thread when request is being initialized and unbinds it when it's being destroyed; Or add &lt;a href="http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/web/filter/RequestContextFilter.html"&gt;RequestContextFilter&lt;/a&gt; which is faster solution 'cause filter allows to map urls.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Lookup code&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; needs http session; it'll get it from thread bound request using: &lt;a href="http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/web/context/request/RequestContextHolder.html#getRequestAttributes%28%29"&gt;RequestContextHolder.getRequestAttributes()&lt;/a&gt;, than&amp;nbsp;casts result to &lt;a href="http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/web/context/request/ServletRequestAttributes.html"&gt;ServletRequestAttributes&lt;/a&gt;, where method of interest - getRequest();&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Implementation of lookup bean:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;public class AccountManagerFactoryBean implements FactoryBean {
    // METHODS        

    public Object getObject() throws Exception {
        return Proxy.newProxyInstance(getClass().getClassLoader(),
                new Class[]{AccountManager.class},
                new BaseInvocationHandler() {
                    protected Class getEJBHomeClass() {
                        return AccountManagerHome.class;
                    }
                });
    }

    public Class getObjectType() {
        return AccountManager.class;
    }

    public boolean isSingleton() {
        return true;
    }
}&lt;/pre&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Where invocation handler that does an actual job:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;public abstract class BaseInvocationHandler implements InvocationHandler {
    // METHODS

    /**
     * Method interceptor which guarantees invocation on EJB object obtained
     * through {@link SessionInfo#ejbProviderUrl}
     *
     * @param proxy  proxy object; not used;
     * @param method method; invocation will be comitted on this method;
     * @throws Throwable either RemoteException or application logic exception;
     * here we dont care about it; application exceptions will be propagated
     * to calling code, RemoteException handling will be defined in spring
     * context xml;
     */
    public Object invoke(Object proxy, Method method, Object[] args)
 throws Throwable {
        String interfaceMethodName = method.getName();
        Class[] parameterTypes = method.getParameterTypes();
        Object ejb =
           services.useSessionEjb(
               getEJBHomeClass(), getSessionInfo().getEjbProviderUrl());
        Method ejbDeclaredMethod =
           ejb.getClass().getDeclaredMethod(interfaceMethodName, parameterTypes);
        if (ejbDeclaredMethod != null) {
            return ejbDeclaredMethod.invoke(ejb, args);
        }
        else {
            // MUST BE UNREACHEBLE;
            throw new AssertionError("Not all methods implemented from the EJB");
        }
    }

    /**
     * Obtains session info object;
     *
     * @return session info object;
     */
    protected final SessionInfo getSessionInfo() {
        // getting request;
        // since we use RequestContextFilter in web.xml and we're
        // in servlet container it's legal to call RequestContextHolder;
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
        // getting http session;
        return SessionInfo.getInstance(request);
    }

    /**
     * @return EJB Home class;
     */
    protected abstract Class getEJBHomeClass();
}
&lt;/pre&gt;&lt;div style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;No need to say about benefits of object which is defined as bean in spring context(Im talking about lookup code placed in spring config xml in a form of FactoryBean(s)). One significant - ability to attach remote exception handler(on an object being created by &lt;a href="http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/aop/framework/ProxyFactoryBean.html"&gt;ProxyFactoryBean&lt;/a&gt;) and there by get rid of hundreds of MyBaseAction.handleRemoteException() calls in web tier code, making it unaware of actual business logic implementation(being it either EJB or POJO) which is great thing!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;Thanks for your time!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/653496027060462681-5669290754721258351?l=artemv12.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/artemv12/~4/Qy9PsAN1bgA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://artemv12.blogspot.com/feeds/5669290754721258351/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://artemv12.blogspot.com/2010/03/using-thread-bound-http-servlet-request.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/5669290754721258351?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/5669290754721258351?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/artemv12/~3/Qy9PsAN1bgA/using-thread-bound-http-servlet-request.html" title="Using thread-bound HttpServletRequest exposed by Spring to bring DI on view tier" /><author><name>artemv12</name><uri>http://www.blogger.com/profile/13734695625317422045</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_pidCk5ODrPM/Sytr85MrQfI/AAAAAAAABEc/8CaZxo7GP6E/S220/ZEa6z.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://artemv12.blogspot.com/2010/03/using-thread-bound-http-servlet-request.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMCQnY_cSp7ImA9WxBXE0g.&quot;"><id>tag:blogger.com,1999:blog-653496027060462681.post-4066063243755554768</id><published>2010-01-24T18:10:00.003+02:00</published><updated>2010-01-24T18:27:43.849+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-24T18:27:43.849+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="RRWL" /><category scheme="http://www.blogger.com/atom/ns#" term="concurrency" /><title>Effects produced by different thread-safe coding styles</title><content type="html">&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Was a bit surprised that different thread-safe coding approaches can impact on app. logic. Suppose we have trivial auth. service like this one: &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public interface Service {
void configChanged() throws Exception;
void login(Session session) throws Exception;
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;It's possible impl.&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public class ThreadSafeServiceImpl implements Service {
 /**
  * Environmental properties;
  */
 private volatile Properties env;

 /**
  * Properties could have been changed;
  */
 public void configChanged() throws Exception {
  Properties env__ = new Properties();
  env__.put("login", property("app.user.login"));
  env__.put("passwrd", property("app.user.passwrd"));
  env__.put("prefs", property("app.user.prefs"));

  env = env__;
 }

 /**
  * Store current user credentials in session;
  */
 public void login(Session session) throws Exception {
  session.getAttribute("creds").apply(env);
 }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Main idea behind service &lt;/span&gt;- login user by storing his info in session. Subsequent business logic would have retrieved "creds" object, checked and either accepts "creds" or throws some kind of application exception there by enforcing currently logged-in user to re-login or preventing unauth. access.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Let's take a look on FastServiceImpl from a point of view of several threads: at first it's safe to access service methods for them, no inconsistency: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;login()&lt;/span&gt; sees very last_ version of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;env&lt;/span&gt;, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;configChanged()&lt;/span&gt; could safely update env and subsequent &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;login()&lt;/span&gt; could have seen either new or old reference to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;env&lt;/span&gt;, but in any case he would haven't seen partly updated &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;env&lt;/span&gt; object. Very ellegant and simple approach, by the way - the same idea is behind &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CopyOnWriteArrayList.html"&gt;CopyOnWriteArrayList&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;So, what is not_ cool about it?! The answer depends on whether it's critical for your app. to support&amp;nbsp; real_ concurrnet access in FastServiceImpl: do you want to manage situation when thread-1 enters &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;configChanged()&lt;/span&gt; and thread-2 at the same time enters &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;login()&lt;/span&gt; (?). If you do_ then keep reading.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;The main issue with service impl. - it doesn't handle concurrent access. Yes, it's thread-safe, but_ it doesn't handle concurrency: it's possible for thread-1 enter w/o a problem &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;configChaned()&lt;/span&gt; and at the same time for thread-2 it's possible to enter, also w/o a problem, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;login()&lt;/span&gt; method. By introducing real concurrent access(not just thread-safe) - we would get a situation where thread-1 should wait if someone accessing &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;login()&lt;/span&gt; at the same time; and vice versa - if thread-2 accessing &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;login()&lt;/span&gt; finds that &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;configChanged()&lt;/span&gt; busy - then thread-2 should wait as well!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;To get this done, first that comes to mind - use &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html"&gt;RRWL&lt;/a&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public class ConcurrentServiceImpl extends ThreadSafeServiceImpl {
 private final ReadWriteLock rw_lock = new ReentrantReadWriteLock();

 @Override
 public void configChanged() throws Exception {
  rw_lock.writeLock().lock();
  try {
   super.configChanged();
  } finally {
   rw_lock.writeLock().unlock();
  }
 }

 @Override
 public void login(Session session) throws Exception {
  rw_lock.readLock().lock();
  try {
   super.login(session);
  } finally {
   rw_lock.readLock().unlock();
  }
 }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Obviously this impl. is better than prev. one: because of support of real_ concurrent access.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Thanks for reading!&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;P.S.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;For those who currious of why &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ThreadSafeServiceImpl.env&lt;/span&gt; has been declared with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;volatile&lt;/span&gt;,&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;read next: &lt;a href="http://www.cs.umd.edu/users/pugh/java/memoryModel/jsr-133-faq.html#volatile"&gt;What does volatile do?&lt;/a&gt; and &lt;a href="http://www.ibm.com/developerworks/library/j-jtp03304/#2.0"&gt;New guarantees for volatile&lt;/a&gt;.&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/653496027060462681-4066063243755554768?l=artemv12.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/artemv12/~4/mycrH1hxSNI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://artemv12.blogspot.com/feeds/4066063243755554768/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://artemv12.blogspot.com/2010/01/effects-produced-by-different-thread.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/4066063243755554768?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/4066063243755554768?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/artemv12/~3/mycrH1hxSNI/effects-produced-by-different-thread.html" title="Effects produced by different thread-safe coding styles" /><author><name>artemv12</name><uri>http://www.blogger.com/profile/13734695625317422045</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_pidCk5ODrPM/Sytr85MrQfI/AAAAAAAABEc/8CaZxo7GP6E/S220/ZEa6z.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://artemv12.blogspot.com/2010/01/effects-produced-by-different-thread.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQGRXk9fCp7ImA9WxBQEEU.&quot;"><id>tag:blogger.com,1999:blog-653496027060462681.post-8672678843972061861</id><published>2010-01-10T02:28:00.000+02:00</published><updated>2010-01-10T02:28:44.764+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-10T02:28:44.764+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="RRWL" /><category scheme="http://www.blogger.com/atom/ns#" term="concurrency" /><title>Fixing "check-then-act" sequence with ReentrantReadWriteLock(RRWL)</title><content type="html">&lt;span style="font-family: Verdana, sans-serif; font-size: x-small;"&gt;Consider&amp;nbsp;multithreaded&amp;nbsp;component with two methods: first one&amp;nbsp;executes&amp;nbsp;highly concurrent operations, e.g. put chat messages to shared concurrent queue, second one plays role of an immediate stopper. See code:&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public class CheckThenAct {
 /**
  * Unbound shared message queue;
  */
 private final ConcurrentLinkedQueue&amp;lt;String&amp;gt; q;

 /**
  * Flag indicating whether operation should proceed;
  */
 private final AtomicBoolean proceed = new AtomicBoolean(true);

 public CheckThenAct(ConcurrentLinkedQueue&amp;lt;String&amp;gt; q) {
  this.q = q;
 }

 public boolean putMessage(String msg) {
  return proceed.get() ? q.offer(msg) : false;
 }

 public boolean stop() {
  return proceed.compareAndSet(true, false);
 }
}
&lt;/pre&gt;&lt;span style="font-family: Verdana; font-size: x-small;"&gt;In the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;putMessage()&lt;/span&gt; method we have "check-than-act" concurrency problem. I.e. when in thread1, thread2, ..., thread20&amp;nbsp;we pass &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;proceed.get()&lt;/span&gt; but just right after that in thread23 we call &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;stop()&lt;/span&gt;, i.e. no more messages, seriously; but in fact twenty messages&amp;nbsp;being added&amp;nbsp;to the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;q&lt;/span&gt;. Since &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;putMessage()&lt;/span&gt; must be highly concurrent I can't make&amp;nbsp;it(and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;stop()&lt;/span&gt;) synchronized. Solution is - to use RRWL:&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;...

private final ReentrantReadWriteLock rw = new ReentrantReadWriteLock();

...

public boolean putMessage(String msg) {
 if (!rw.readLock().tryLock())
  return false;
 try {
  return proceed.get() ? q.offer(msg) : false;
 } finally {
  rw.readLock().unlock();
 }
}

public boolean stop() {
 rw.writeLock().lock();
 try {
  return proceed.compareAndSet(true, false);
 } finally {
  rw.writeLock().unlock();
 }
}
&lt;/pre&gt;&lt;span style="font-family: Verdana; font-size: x-small;"&gt;Let me explain why:&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana; font-size: x-small;"&gt;- Read lock in putMessage() doesn't bring serialized behaviour, method still is highly concurrent;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana; font-size: x-small;"&gt;- Read lock being acquired only when &lt;em&gt;there is&lt;/em&gt; no write lock;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana; font-size: x-small;"&gt;- Write lock being acquired only when &lt;em&gt;there are&lt;/em&gt; no read locks;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana; font-size: x-small;"&gt;- Write lock is exclusive;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Verdana; font-size: x-small;"&gt;So, main demand satisfied - truly shared access in putMessage() and remedy the "check-then-act" behaviour!&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Verdana; font-size: x-small;"&gt;Thanks for reading!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/653496027060462681-8672678843972061861?l=artemv12.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/artemv12/~4/z0wDJo8IVzs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://artemv12.blogspot.com/feeds/8672678843972061861/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://artemv12.blogspot.com/2010/01/fixing-check-then-act-sequence-with.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/8672678843972061861?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/8672678843972061861?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/artemv12/~3/z0wDJo8IVzs/fixing-check-then-act-sequence-with.html" title="Fixing &quot;check-then-act&quot; sequence with ReentrantReadWriteLock(RRWL)" /><author><name>artemv12</name><uri>http://www.blogger.com/profile/13734695625317422045</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_pidCk5ODrPM/Sytr85MrQfI/AAAAAAAABEc/8CaZxo7GP6E/S220/ZEa6z.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://artemv12.blogspot.com/2010/01/fixing-check-then-act-sequence-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQMQH0zcSp7ImA9WxBQEEo.&quot;"><id>tag:blogger.com,1999:blog-653496027060462681.post-4754150961369441818</id><published>2010-01-09T03:55:00.002+02:00</published><updated>2010-01-10T00:49:41.389+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-10T00:49:41.389+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="RRWL" /><category scheme="http://www.blogger.com/atom/ns#" term="concurrency" /><title>Alternative look at ReentrantReadWriteLock(RRWL)</title><content type="html">&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;I adore to hunt for non-standard/non-documented properties/usages/features of old-good(and standard) utilities.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Lets take &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html"&gt;ReentrantReadWriteLock&lt;/a&gt;(RRWL) - it's more than five years old(in Java env. of course) concurrency utility aimed chiefly for efficient separation of shared read and exclusive write operations. Definitely look for more in javadoc. What is interesting about RRWL is that examples rendering its usage usually concentrate attention on the fact that readLock() guards 'read' operations and writeLock() guards 'write' operations. Let me show:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public class RRWLockRegularCase {
 private final ReentrantReadWriteLock rw = new ReentrantReadWriteLock();
 private final ReadLock r = rw.readLock();
 private final WriteLock w = rw.writeLock();

 private final char[] arr = new char[] { 'c', 'o', 'o', 'l', '!' };

 public void iterate() {
  r.lock();
   for (char c : arr) {
   }
  r.unlock();
 }

 public void modify() {
  w.lock();
   arr[4] = '?';
  w.unlock();
 }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;And this one from javadoc:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;class RWDictionary {
    private final Map&amp;lt;String, Data&amp;gt;  m = new TreeMap&amp;lt;String, Data&amp;gt;();
    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    private final Lock r = rwl.readLock();
    private final Lock w = rwl.writeLock();

    public Data get(String key) {
        r.lock(); try { return m.get(key); } finally { r.unlock(); }
    }
    public String[] allKeys() {
        r.lock(); try { return m.keySet().toArray(); } finally { r.unlock(); }
    }
    public Data put(String key, Data value) {
        w.lock(); try { return m.put(key, value); } finally { w.unlock(); }
    }
    public void clear() {
        w.lock(); try { m.clear(); } finally { w.unlock(); }
    }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;From examples it's obviously that readLock() guards read(R) operations: get(String), allKeys(), iterate(); and writeLock() - clear(), put(String, Data), modify() - write(W) operations.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;But do you know that RRWL could be used in an alternative way?!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Suppose we have appl. component that tracks user activity: when user came to site, what page he entered and so on. It would be Map with key customerId and value - list of log messages. To simplify concurr. map access there's a rule: customerId isn't shared among threads. Also it's known that component has two methods: saveOrUpdate() - for saving/updating activity log messages and clearThemAll() method for removing logs from memory. Like this:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public class RRWLockUnusualCase {
 /**
  * Pairs like [customerId, list of log messgs] e.g.: [100,
  * {"opened session at 10/10/2010 00:14:40",
  * "entered on main_page at 00:14:45", "entered help_page at 00:16:21"}];
  * customerId is strictly thread bound i.e. it's impossible seeing two
  * threads sharing same customerId(think of it like of business logic
  * restriction);
  */
 private final ConcurrentMap&amp;lt;Long, List&amp;lt;String&amp;gt;&amp;gt; customerActionLog;

 public RRWLockUnusualCase(ConcurrentMap&amp;lt;Long, List&amp;lt;String&amp;gt;&amp;gt; customerActionLog) {
  this.customerActionLog = customerActionLog;
 }

 public void saveOrUpdate(Long customerId, String messg) {
  if (customerActionLog.get(customerId) != null) {
   customerActionLog.get(customerId).add(messg);
  } else {
   customerActionLog.put(customerId, Arrays.asList(messg));
  }
 }
 
 public void clearThemAll() {
  for (Long k : customerActionLog.keySet()) {
   customerActionLog.remove(k);
  }
 }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;The main drawback - not thread-safe(in spite of ConcurrentMap) 'cause suffers from "check-then-act" problem:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;...
if (customerActionLog.get(customerId) != null) {
customerActionLog.get(customerId).add(messg);
...
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;On second line we run into trouble if after first one method clearThemAll()* removes target entry, *which could being executed concurrently. To fix, first that occurs to me - synchronization on object &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;customerActionLog&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public void saveOrUpdate(Long customerId, String messg) {
 synchronized (customerActionLog) {
  ...
 }  
}

public void clearThemAll() {
 synchronized (customerActionLog) {
  ...
 }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Which is bad idea since &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;serializing saveOrUpdate() i&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;s inadmissible. There is an alternative to synchronization. What we have: tons of threads executing saveOrUpdate(), write activity logs in a non-blocking manner; issue comes when we need to clearThemAll(). In latter method would be logical to &lt;i&gt;wait until all saveOrUpdate() operations have finished&lt;/i&gt; and only_ &lt;i&gt;after this proceed(exclusively) with clearing&lt;/i&gt;. This transforms to:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public class RRWLockUnusualCase {
 private final ReentrantReadWriteLock rw = new ReentrantReadWriteLock();
 private final ReadLock r = rw.readLock();
 private final WriteLock w = rw.writeLock();

 // Same as above ...
 
 public void saveOrUpdate(Long customerId, String messg) {
  r.lock();
  try {
   // Same as above ...
  } finally {
   r.unlock();
  }
 }

 public void clearThemAll() {
  w.lock();
  try {
   // Same as above ...
  } finally {
   w.unlock();
  }
 }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;So that was an 'alternative look' - readLock() doesn't protected 'read' operation - it protects shared operation.&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;And finally pattern, I believe:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public class RRWLockPattern {
 private final ReentrantReadWriteLock rw = new ReentrantReadWriteLock();
 private final ReadLock r = rw.readLock();
 private final WriteLock w = rw.writeLock();

 // ...

 /**
  * Can be executed concurrently if there is no exclusive operation
  * currently being executed;
  */
 public void sharedOperation() {
  r.lock();
  try {
   // PUT SHARED OPERATION LOGIC HERE
  } finally {
   r.unlock();
  }
 }

 /**
  *  Can be executed only exclusively i.e. by single thread;
  *  In case of shared operations currently being executed - blocks
  *  until all_ shared operations have completed; 
  */
 public void exclusiveOperation() {
  w.lock();
  try {
   // PUT EXCLUSIVE OPERATION LOGIC HERE
  } finally {
   w.unlock();
  }
 }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Thanks for reading!&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/653496027060462681-4754150961369441818?l=artemv12.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/artemv12/~4/sbGTXuuCJoI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://artemv12.blogspot.com/feeds/4754150961369441818/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://artemv12.blogspot.com/2010/01/alternative-look-at-reentrantreadwritel.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/4754150961369441818?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/4754150961369441818?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/artemv12/~3/sbGTXuuCJoI/alternative-look-at-reentrantreadwritel.html" title="Alternative look at ReentrantReadWriteLock(RRWL)" /><author><name>artemv12</name><uri>http://www.blogger.com/profile/13734695625317422045</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_pidCk5ODrPM/Sytr85MrQfI/AAAAAAAABEc/8CaZxo7GP6E/S220/ZEa6z.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://artemv12.blogspot.com/2010/01/alternative-look-at-reentrantreadwritel.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkADRHw-fip7ImA9WxBbEU8.&quot;"><id>tag:blogger.com,1999:blog-653496027060462681.post-2592929255389113006</id><published>2010-01-08T21:30:00.007+02:00</published><updated>2010-03-09T10:52:55.256+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-09T10:52:55.256+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="concurrency" /><title>Revealing FutureTask's hidden property</title><content type="html">&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;As you may know j&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/FutureTask.html"&gt;ava.util.concurrent.FutureTask&lt;/a&gt; is used to encapsulate deferred computation and the result of that compuatation. &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;We accustomed to use it jointly with &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executor.html"&gt;Executor&lt;/a&gt; by submitting it to thread pool and retrieving result in a blocked fashion with future.get() method. Nothing new so far.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;You know, as for me it's a lot of fun finding standard utility, like FutureTask, being used in an alternative way! What if you haven't an Executor but still wants to use FutureTask's core principle - one thread does a job, others - should wait. So you have just current thread and want your current stuff being done in current thread at the same time having other workers, who migth came at the same execution point, being waited for the computation result.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Easily: &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public class NiceFutureFeature {
 private final AtomicReference&amp;lt;FutureTask&amp;gt; f = new AtomicReference&amp;lt;FutureTask&amp;gt;();

 public Object work(Callable c) throws InterruptedException, ExecutionException {
  if (f.compareAndSet(null, new FutureTask(c))) {
   // Only one thread will pass and will do the job
   f.get().run();
  }
  // Since we didn't pass we should wait for result
  return f.get().get();
 }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;In this class atomic reference ensures that only one thread will proceed with f.run(), others will wait. Core point - atomically restrict access to task execution to only one worker.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;I believe this approach would be useful when we meet execution of idempotent operations at the same time. E.g.:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;idempotent business routine that includes sql query and is being executed by n threads at a given time, i.e. if you had stopped time you would have seen n threads going to hit db with same sql(I checked that on Toplink)! No problem if you execute methods sequentally, i.e. hit db - put result in cache - next time execute method and get result from cache, the issue appears when you perform operations concurrently. In this regard let me extend code above:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public class NiceFutureFeature {
 /**
  * Key of type List; Could be in the form:
  * ["select id from Emp e where e.id=:id and e.salary=:salary", 100, 2000]
  */
 private final ConcurrentMap&amp;lt;List, FutureTask&amp;gt; cm = new ConcurrentHashMap&amp;lt;List, FutureTask&amp;gt;();

 public Object work(List key, Callable c) throws InterruptedException, ExecutionException {
  FutureTask f = new FutureTask(c);
  if (cm.putIfAbsent(key, f) == null) {
   // Only one will pass and will do the job
   f.run();
  }
  // Since we didn't pass we should wait for result
  return cm.get(key).get();
 }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Same principle applied in this code to guard main idea by using atomical putIfAbsent() method.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Thanks for reading!&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/653496027060462681-2592929255389113006?l=artemv12.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/artemv12/~4/c_qDEToPpt0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://artemv12.blogspot.com/feeds/2592929255389113006/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://artemv12.blogspot.com/2010/01/revealing-javautilconcurrentfuturetasks.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/2592929255389113006?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/2592929255389113006?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/artemv12/~3/c_qDEToPpt0/revealing-javautilconcurrentfuturetasks.html" title="Revealing FutureTask's hidden property" /><author><name>artemv12</name><uri>http://www.blogger.com/profile/13734695625317422045</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_pidCk5ODrPM/Sytr85MrQfI/AAAAAAAABEc/8CaZxo7GP6E/S220/ZEa6z.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://artemv12.blogspot.com/2010/01/revealing-javautilconcurrentfuturetasks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QEQng7fyp7ImA9WxBRFk8.&quot;"><id>tag:blogger.com,1999:blog-653496027060462681.post-5446942901174464000</id><published>2010-01-04T19:13:00.001+02:00</published><updated>2010-01-04T19:15:03.607+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-04T19:15:03.607+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="aspectj" /><title>Limitations of percflow/percflowbelow instantiation modes in AspecJ5</title><content type="html">&lt;span style="font-family: Verdana,sans-serif; font-size: x-small;"&gt;Recently I enjoyed percflow/percflowbelow advanced instantiation modes in aspectj; but later found considerable limitation(from my point of view) - they are thread bound. In this mode Aspect's TTL is limited to flow-of-execution - ok, this is what they had been designed for, but what if that flow-of-exec. initiates another thread underneath and submit execution unit like callable/runnable to it - wouldn't be nice if that submitted unit could be weaved by aspect as well?&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana,sans-serif; font-size: x-small;"&gt;Suppose we have code like:&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public void testConcurrentLogic() {
 ExecutorService exec = ...
 Future f = exec.submit(runnable);
 assert...(f.get());
}
&lt;/pre&gt;&lt;span style="font-family: Verdana,sans-serif; font-size: x-small;"&gt;The issue is - need an aspect with lifecycle bound to testConcurrentLogic() and with ability to match joint points in runnable.run().&amp;nbsp;At current, first part is doable with percflow instantiation mode, second one - isn't.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/653496027060462681-5446942901174464000?l=artemv12.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/artemv12/~4/Oo74QcSNRMU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://artemv12.blogspot.com/feeds/5446942901174464000/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://artemv12.blogspot.com/2010/01/limitations-of-percflowpercflowbelow.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/5446942901174464000?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/5446942901174464000?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/artemv12/~3/Oo74QcSNRMU/limitations-of-percflowpercflowbelow.html" title="Limitations of percflow/percflowbelow instantiation modes in AspecJ5" /><author><name>artemv12</name><uri>http://www.blogger.com/profile/13734695625317422045</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_pidCk5ODrPM/Sytr85MrQfI/AAAAAAAABEc/8CaZxo7GP6E/S220/ZEa6z.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://artemv12.blogspot.com/2010/01/limitations-of-percflowpercflowbelow.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEGQHk5fCp7ImA9WxBQEEU.&quot;"><id>tag:blogger.com,1999:blog-653496027060462681.post-8286446974118372126</id><published>2009-12-29T20:13:00.002+02:00</published><updated>2010-01-10T02:33:41.724+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-10T02:33:41.724+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="interruption" /><category scheme="http://www.blogger.com/atom/ns#" term="concurrency" /><category scheme="http://www.blogger.com/atom/ns#" term="aspectj" /><title>Overcoming limitations of ExecutorService.shutdownNow(), transparently with AspectJ5</title><content type="html">&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt;The "Chapter 7. Cancellation and Shutdown" of &lt;a href="http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601"&gt;Java Concurrency in Practice&lt;/a&gt; book(as well as &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow%28%29"&gt;javadoc&lt;/a&gt; of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ExecutorService.shutdownNow()&lt;/span&gt;) says that there is limitation applied on what is being returned by shutdownNow().&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt;The book says:&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;blockquote style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt;"When an ExecutorService is shut down abruptly with shutdownNow, it attempts to cancel the tasks currently in progress and returns a list of tasks that were submitted but never started so that they can be logged or saved for later processing. However, there is no general way to find out which tasks started but did not complete. This means that there is no way of knowing the state of the tasks in progress at shutdown time unless the tasks themselves perform some sort of checkpointing. To know which tasks have not completed, you need to know not only which tasks didn't start, but also which tasks were in progress when the executor was shut down."&lt;/span&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Also author provides us with work-around to this problem, by extending &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;AbstractExecutorService&lt;/span&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;, overriding &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;submit(Runnable)&lt;/span&gt; and defining method that returns cancelled tasks. But all the same, in this case we are enforced to use shutdownNow() in a next fashion:&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;...
//hint to running tasks to stop what they are doing!
exec.shutdownNow();
//wait until all running tasks stopped, and gathered in some "cancelled tasks collection" (but how long?!)
exec.awaitTermination(TIMEOUT, UNIT);
//here is our result!
exec.getCancelledTasks();
...
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;And yet, in proposed solution there is a requirement - tasks should be responsive to interruption. In &lt;a href="http://artemv12.blogspot.com/2009/12/proof-of-concept-true-interruption.html"&gt;this post&lt;/a&gt; I wrote why this req. is difficult to achieve(would say impossible).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Being in no way a critic of what suggested in Java Concurrency in Practice, let me share alternative solution.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Goal is put as few requirements as possible on the clients of &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ExecutorService.shutdownNow()&lt;span style="font-family: Verdana,sans-serif;"&gt;:&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; &lt;span style="font-family: Verdana,sans-serif;"&gt;as a user of executor service I want to obtain it through Executors factory, then submit tasks to it(tasks either sensitive to interruption or not!), when time comes - call ExecutorService.shutdownNow() and in a guaranteed fashion get all cancelled tasks(queued but didn't started and started ones but didn't completed). Also, don't want to extend abstract executor service and deal with new type and its new method.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;It's "doable" - with AspectJ5.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;The solution primarily relies on: &lt;a href="http://artemv12.blogspot.com/2009/12/proof-of-concept-true-interruption.html"&gt;instant interruption handling&lt;/a&gt;, atomic variables, synchronized collection and AOP magic.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Before looking into the code, in "two words" let me describe how stuff does work:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;- when you submit callable/runnable to executor service it's picked out from work-queue by available thread and then its exec. flow reaches to call()/run() - at this point I assert that task is at the first step of execution - this execution point is caught with AOP which tracks this fact by atomically inrementing number of running tasks.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;- once task(either callable/runnable) started executing - at this point its behaviour is handled in a next way: if task throws checked/unchecked exception from its call()/run() method - it's ok, task being considered as completed and &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;number of running tasks atomically decremented&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;; but if during task execution it appears that thread was requested for interruption - instant interruption handling comes to play - runtime exception is being thrown, task added to collection of cancelled tasks and number of running tasks atomically decremented.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;- as you might guess, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ExecutorService.shutdownNow()&lt;/span&gt;(dressed with AOP) after requesting interruption of all running tasks - merely loops until &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;number of running tasks&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt; becomes 0, and thanks to instant interruption handling - loop is finite!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Meet the ExecutorServiceShutdownNowAspect:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public aspect ExecutorServiceShutdownNowAspect {
 /////////////////////////////////////////////
 // ATTRIBUTES

 /**
  * Collection of interrupted workers;
  */
 private List&amp;lt;Runnable&amp;gt; interruptedWorkers = Collections
   .synchronizedList(new ArrayList&amp;lt;Runnable&amp;gt;());

 /**
  * Number of tasks currently being executed;
  */
 private volatile AtomicInteger activeTasksNum = new AtomicInteger();

 /////////////////////////////////////////////
 // POINCUTS

 /**
  * Matches {@link Callable#call()}-s;
  */
 pointcut executionOfCallable_() : execution(* Callable.call());

 /**
  * Matches {@link Callable#call()}-s;
  */
 pointcut executionOfCallable(Callable task) : executionOfCallable_() &amp;amp;&amp;amp; this(task);

 /**
  * Compilation hint;
  */
 pointcut notwithin() :
  !within(eg.ExecutorServiceShutdownNowLimitationTest) &amp;amp;&amp;amp; !within(ExecutorServiceShutdownNowAspect);

 /////////////////////////////////////////////
 // ADVICES

 /**
  * Check for interruption before every call of a method that doesn't throw
  * {@link InterruptedException};
  */
 before(Callable task) :
  cflow(executionOfCallable(task)) &amp;amp;&amp;amp; call(* *(..) throws !InterruptedException) &amp;amp;&amp;amp; notwithin() {
  if (interrupted()) {
   handleInterruption(task, new InterruptedException());
  }
 }

 /**
  * Handles interruption exception in the flow of execution of
  * {@link Callable#call()};
  */
 after(Callable task) throwing (InterruptedException e) :
  cflow(executionOfCallable(task)) &amp;amp;&amp;amp; notwithin() {
  handleInterruption(task, e);
 }

 Object around() : executionOfCallable_() &amp;amp;&amp;amp; notwithin() {
  // increment number of tasks currently being executed;
  activeTasksNum.incrementAndGet();
  try {
   // let execution of callable.call() proceed;
   return proceed();
  } finally {
   // decrement number of running tasks depending on interruption
   // status;
   if (!interrupted()) {
    activeTasksNum.decrementAndGet();
   }
  }
 }

 /**
  * Decorates task collection returned by
  * {@link ExecutorService#shutdownNow()} by adding to it interrupted tasks;
  */
 List&amp;lt;Runnable&amp;gt; around() : call(List&amp;lt;Runnable&amp;gt; ExecutorService.shutdownNow()) {
  interruptedWorkers.addAll(proceed());

  // wait until all active tasks have interrupted;
  while (activeTasksNum.get() != 0) {
  }

  // workaround caused by aspect's instantiation mode issue; 
  // in reality we should simply return interruptedWorkers;
  List&amp;lt;Runnable&amp;gt; ret = interruptedWorkers;
  interruptedWorkers = Collections
    .synchronizedList(new ArrayList&amp;lt;Runnable&amp;gt;());

  return ret;
 }

 /////////////////////////////////////////////
 // METHODS

 private void handleInterruption(Callable task, InterruptedException e) {
  Thread.currentThread().interrupt();
  interruptedWorkers.add(new FutureTask(task));
  activeTasksNum.decrementAndGet();
  throw new RuntimeException(e);
 }

 private boolean interrupted() {
  return Thread.currentThread().isInterrupted();
 }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;More words on instant interruption - this is implemented by dynamically adding a check for current thread's interruption status by means of 'before' advice. Before every method call in the execution flow of callable.call() the code &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;if (interrupted())&lt;/span&gt; is being executed. Actually, not before every_ method call, but only before methods that don't throw &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;InterruptedException&lt;/span&gt;. As for this exception, it has interesting treatment, would say, very serious treatment: once throw of &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;InterruptedException &lt;span style="font-family: Verdana,sans-serif;"&gt;detected - aspect doesn't play with it - set interruption status of current thread to 'true', saves current callable, atomically decrements number of running tasks and finally throws &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;RuntimeException&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;private void handleInterruption(Callable task, InterruptedException e) {
 Thread.currentThread().interrupt();
 interruptedWorkers.add(new FutureTask(task));
 activeTasksNum.decrementAndGet();
 throw new RuntimeException(e);
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Instant interruption handling isn't single interesting thing. Look into the code, read comments and you will find more.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;What is great about aspectj - readability&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt; 8)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;A few words about testing.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Several cases/situations have been considered - all of them succeeded. Let me describe them briefly:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Wrong interruption handling:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;void method() throws InterruptedException {
 ...
 synchronized (lock) {
   try {
      // let "emulate" blocking;
      lock.wait();
   } catch (InterruptedException ignore) {
      // case: ignorance of interruption;
   }
 }
 Thread.sleep(10000);
 ...
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Re-throwing interrupted exception:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;void method() throws InterruptedException {
 ...
 // case: interrupted exception throwing;
 Thread.sleep(10000);
 ...
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Throwing checked exception:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;void method() throws Exception {
 ...
 // case: application exception;
 throw new CheckedException();
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Regular code insensible to standard interruption mechanism:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;void method() {
 // lets "emulate" task insensible to standard interruption mechanism;
 for (;;) {
  anotherRegularMethod();
 }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;At current, that's all cases/situations I devised. Will update post once invent new one. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;I used TestNG framework to write test code, since it gives overhelming benefit over JUnit4 when you deal with single test body and several cases/situations for which this test aimed. Here is test code itself:&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;@Test
public void abruptPoolTermination(AbstractCallableFactory f,
                                  int expectingTaskNum)
  throws InterruptedException {
 ExecutorService exec = Executors.newFixedThreadPool(THREAD_NUM);
 exec.submit(f.callable());
 exec.submit(f.callable());
 exec.submit(f.callable());
 Thread.sleep(200);
 Assert.assertEquals(exec.shutdownNow().size(), expectingTaskNum);
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;In summary.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Should say it's very enjoyable to overcome existing java limits with aspectj, since it's not hard, it doesn't require from you an ability to mentally multiply hex digits; and even more - once you know java's concurreny rules - same rules could be legally applied in aspectj!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;
Thanks for your time! &lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/653496027060462681-8286446974118372126?l=artemv12.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/artemv12/~4/dRFbYJ10wzw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://artemv12.blogspot.com/feeds/8286446974118372126/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://artemv12.blogspot.com/2009/12/overcoming-limitations-of.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/8286446974118372126?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/8286446974118372126?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/artemv12/~3/dRFbYJ10wzw/overcoming-limitations-of.html" title="Overcoming limitations of ExecutorService.shutdownNow(), transparently with AspectJ5" /><author><name>artemv12</name><uri>http://www.blogger.com/profile/13734695625317422045</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_pidCk5ODrPM/Sytr85MrQfI/AAAAAAAABEc/8CaZxo7GP6E/S220/ZEa6z.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://artemv12.blogspot.com/2009/12/overcoming-limitations-of.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUENQXg-eCp7ImA9WxBQEEU.&quot;"><id>tag:blogger.com,1999:blog-653496027060462681.post-341702651739880276</id><published>2009-12-15T20:19:00.009+02:00</published><updated>2010-01-10T02:34:50.650+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-10T02:34:50.650+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="interruption" /><category scheme="http://www.blogger.com/atom/ns#" term="concurrency" /><category scheme="http://www.blogger.com/atom/ns#" term="aspectj" /><title>Proof-of-concept: true interruption handling, transparently with AspectJ5</title><content type="html">&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Perhaps, you know what &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/InterruptedException.html"&gt;InterruptedException&lt;/a&gt; does mean in java. In either case, let me describe it a little. Javadoc will not allow me to deceive you. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;So, a method is interruptable if it: (a) throws InterrupedException; (b) has a logic that actually throws this kind of exception; It's simple - each thread, i.e. &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Thread.html"&gt;Thread&lt;/a&gt; object, has flag-field that holds interruption status. So, for a method to be cancellable(this word is better) - it must poll for interruption status with &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#isInterrupted%28%29"&gt;Thread.isInterrupted()&lt;/a&gt; and if it is eq. "true" throw InterruptedException, clearing the status at first.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;There are a lot of methods in java that throws InterrupedException: Object.wait(), Future.get(), Thread.sleep(), CountDownLatch.await() and etc. etc. and many others. Applying to them what I have already told we can assert that these methods checks interruption status of thread in which they are being executed, and throw an exception if it's case. In other words, regardless of when thread was being interrupted, i.e. before_ calling a method that throws InterruptedException or during_ execution of that method, method in either case will catch interruption status and will throw exception.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Pretty simple so far: just poll for interruption status and throw the exception, and let code at higher level treat that damn exception as he wants. So, where is issue with all of this?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;As for me there is a big issue: it's impossible to make all the code, under execution thread, being explicitly interruptible, because you can't make all_ your code sensible to interruption. Got it?&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Let put this into code(&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;try to imagine that code is meaningfull&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;): &lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;public abstract class Service {

 public Object doSomeDb(long id) {
  return findItemInDb(id);
 }

 abstract Object findItemInDb(long id);

 public void doSomeOperation(InputStream in, OutputStream out) throws IOException {
  if (doSomeDb(100L) != null) {
   executeIOStuff(in, out);
  }
 }

 void executeIOStuff(InputStream in, OutputStream out) throws IOException {
  byte[] buff = new byte[4096];
  while (in.read(buff) != -1) {
   out.write(buff);
  }
 }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;If thread's execution flow which is currently being executed, at given moment of time is in the doSomeOperation() method, and our current thread isn't yet interrupted - it's ok, we proceed successfully with doSomeDb()&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;and return from it. After that, it appears - when we were in doSomeDb(), during this time, someone who has access to our thread's reference, &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#interrupt%28%29"&gt;requested interruption on it&lt;/a&gt;; so, at this point, logically, we must instantly abort execution of our thread; unfortunately - not so, java will proceed with executeIOStuff() which in turn will do old IO operations, which aren't interruptable; But even if they were interruptable&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;(like NIO operations)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt; - it's wrong to execute something after a thread interruption.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;So, now I hope you caught the core point - no_ operations after thread interruption! How to do this? While you think, let me introduce aspectj solution that effectively fix_ this.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;At first, how_ we will fix?! I believe, dynamically checking thread's interruption status before and after every method call and throwing runtime exception if it's case, would be sufficient(especially in the context of &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;"proff-of-concept solution"&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Let me introduce aspect that &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;effectively reflects exactly the same as I have said:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;@Aspect
public aspect InterruptionAspect {
 @Pointcut("cflow(call(void majorFlow())&amp;amp;&amp;amp;target(b))&amp;amp;&amp;amp;call(* *(..))&amp;amp;&amp;amp;!within(InterruptionAspect)")
 public void everyMethodCallInTheControlFlowOfMajorFlowMethod(B b) {
 }

 @Before("everyMethodCallInTheControlFlowOfMajorFlowMethod(b)")
 public void adviceAfter(B b) {
  checkInterruption(b);
 }

 void checkInterruption(B b) {
  if (Thread.interrupted()) {
   b.interrupedBy = STATUS_MAJOR_FLOW_INTERRUPTED_ASAPLY;
   throw new CleverInterruptedException();
  }
 }
} 
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Take a look on requestInstantInterruption(): if current thread has been interrupted - then stop any actions and abort execution(in java it's possible only through exception mechanism).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Unit test them all. &lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public class A {
 static final int STATUS_MAJOR_FLOW_INTERRUPTED_NORMALY = 1;
 static final int STATUS_MAJOR_FLOW_INTERRUPTED_ASAPLY = 2;

 /**
  * @see #STATUS_MAJOR_FLOW_INTERRUPTED_NORMALY
  * @see #STATUS_MAJOR_FLOW_INTERRUPTED_ASAPLY
  */
 volatile int interrupedBy;

 /**
  * Flag that indicates that computation in {@link #methodUnsensitiveToInterruption} has occured;
  */
 volatile boolean we_were_in_methodUnsensitiveToInterruption;

 /**
  * Entry point to class functionality;
  */
 public void majorFlow() {
  methodUnsensitiveToInterruption();
  try {
   blockingOperation();
  } catch (InterruptedException e) {
   // setting back the status of current thread to interrupted, so higher level code that
   // polls for thread's status could catch it.
   Thread.currentThread().interrupt();
   interrupedBy = STATUS_MAJOR_FLOW_INTERRUPTED_NORMALY;
  }
 }

 private void blockingOperation() throws InterruptedException {
  Thread.sleep(1000000L);
 }

 private void methodUnsensitiveToInterruption() {
  // just method...that is unsensitive to interruption, i.e. when we come here and current
  // thread's status is interrupted, we wouldn't know that and instead of stopping we would
  // proceed
  we_were_in_methodUnsensitiveToInterruption = true;
 }
}

public class B extends A {
}

public class CleverInterruptedException extends RuntimeException {
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Class A: entry point is majorFlow() method. Under regular(without apllying aspect logic) interruption majorFlow() will abort its execution only in the blockingOperation(). I.e. if thread is being interrupted before methodUnsesitiveToInterruption(), under "normal java" this will be revealed only in the operation that throws InterruptedException, in our case - in blockingOperation(). So, under regular conditions the flag we_were_in_methodUnsensitiveToInterruption will be "true" and interruptedBy will be ...INTERRUPTED_NORMALLY.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Actually unit tests:&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;public class TestAdvancedInterruption {
 private final ExecutorService executor = Executors.newSingleThreadExecutor();

 private static class MyTask implements Callable {
  final A target;

  public MyTask(A a) {
   this.target = a;
  }

  public A call() {
   // Logically, at start thread isn't interrupted
   // Lets "emulate" interruption;
   Thread.currentThread().interrupt();
   // watch out for CleverInterruptedException!
   try {
    target.majorFlow();
   } 
   catch (CleverInterruptedException ignore) {
    // It's ok to ignore it here, but don't forget to set the status;
    Thread.currentThread().interrupt();
   }
   return target;
  }
 };

 @Test
 public void handleInterruption_Normaly() throws Exception {
  A a_state = executor.submit(new MyTask(new A())).get();
  assertEquals(STATUS_MAJOR_FLOW_INTERRUPTED_NORMALY, a_state.interrupedBy);
  assertTrue(a_state.we_were_in_methodUnsensitiveToInterruption);
 }

 @Test
 public void handleInterruption_ASAP() throws Exception {
  B b_state = (B) executor.submit(new MyTask(new B())).get();
  assertEquals(STATUS_MAJOR_FLOW_INTERRUPTED_ASAPLY, b_state.interrupedBy);
  assertFalse(b_state.we_were_in_methodUnsensitiveToInterruption);
 }
}
&lt;/pre&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;After applying aspect picture becomes totally different - handleInterruption_ASAP() tests aspect "presence": I assert that interruptedBy status now eq. to ...INTERRUPTED_ASAPLY and it's false that we were in methodUnsensitiveToInterruption! Stop here. You see - we fixed the issue - thread was being interrupted before call to methodUnsensitiveToInterruption() and_ code, thanks to aspectj, handled that immediately!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Thanks for reading and for your time!&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/653496027060462681-341702651739880276?l=artemv12.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/artemv12/~4/H9JCfbfQUZ0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://artemv12.blogspot.com/feeds/341702651739880276/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://artemv12.blogspot.com/2009/12/proof-of-concept-true-interruption.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/341702651739880276?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/341702651739880276?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/artemv12/~3/H9JCfbfQUZ0/proof-of-concept-true-interruption.html" title="Proof-of-concept: true interruption handling, transparently with AspectJ5" /><author><name>artemv12</name><uri>http://www.blogger.com/profile/13734695625317422045</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_pidCk5ODrPM/Sytr85MrQfI/AAAAAAAABEc/8CaZxo7GP6E/S220/ZEa6z.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://artemv12.blogspot.com/2009/12/proof-of-concept-true-interruption.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQASXo4eSp7ImA9Wx5aGUU.&quot;"><id>tag:blogger.com,1999:blog-653496027060462681.post-1291698038748865302</id><published>2009-12-11T23:13:00.019+02:00</published><updated>2010-11-17T10:59:08.431+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-17T10:59:08.431+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="aspectj" /><title>Proof-of-concept: log in separate thread, transparently with AspectJ5</title><content type="html">&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;Suppose there is a case, when logging tasks grab a lot of processing time/memory or probably another "a lot of", e.g. tens of threads at the same time try to acquire a write-lock on resource(e.g. file) or it might appeared that logging routine is costly because it touches network IO.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;So, in either case, we decided to log asynchronously. What we have: thousands of &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;Logger.log() calls spread across the code. One obvious way - digg into 3rd party logger src and change log() behaviour so that each call on it will be wrapped in the "log-task" and forwarded underneath to the thread pool. From first sight it's pretty simple, but from the other one - there are drawbacks:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;- changing 3rd party isn't good idea;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;- weird impl., because now I must support logging_asynchronuosly_version1_my_impl_of_3rdparty.jar;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;- hard to plugg-in/plugg-out;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;- biggest one: not a granular implementation, since it encompasses all_ calls to Logger.log(), while one might want apply target behaviour only to a manageable subset of code, e.g. to integration test code.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;Anyway, whether someone would argue about points above or no, there is an alternative that hasn't mentioned drawbacks (but certainly has another ones, like any solution).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;Lets summarize requirements : impl. should be flexible, pluggable, granular(means no "all-or-nothing" approaches), transparent(no code changes).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;The loggers are as following:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;public class AnotherLogger extends Logger {
    @Override
    void log() {
        System.out.println("\t\tlogging in " + this.getClass().getCanonicalName());
    }
}

public class Logger {
    void log() {
        try {
            Thread.sleep(1000L);
        } catch (InterruptedException ignore_here) {}
        System.out.println("\t\tlogging in " + this.getClass().getCanonicalName());
    }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; font-size: small;"&gt;Their "runtime":&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint"&gt;public class LoggerTest {
    @Test
    public void test_LoggerLog() throws Exception {
        test(new Logger());
    }

    @Test
    public void test_LoggerOverridenLog() throws Exception {
        test(new AnotherLogger());
    }

    private void test(Logger logger) throws Exception {
        System.out.println("[" + Thread.currentThread().getName() + "]: about to log()");
        logger.log();
        System.out.println("[" + Thread.currentThread().getName() + "]: after log()");
        Thread.sleep(2000L);
        System.out.println("\ntest done: good bye synchronous logging!");
    }
}
&lt;/pre&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;With all that we have next output:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; font-family: Verdana,sans-serif; text-align: center;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;a href="http://4.bp.blogspot.com/_pidCk5ODrPM/SyKpTJw3NnI/AAAAAAAABEM/BXGFIJvfQgo/s1600-h/1.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_pidCk5ODrPM/SyKpTJw3NnI/AAAAAAAABEM/BXGFIJvfQgo/s400/1.PNG" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;You can see logging occurs in main thread, stuff proceeds in synchronous way.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;But very soon this will be refactored with AspecJ5 and its AOP "magic". &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;Meet the "aspect":&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;@Aspect
public class WrapLoggingInSeparateThreadTransparently {
    private final ExecutorService executor = Executors.newFixedThreadPool(1);

    /**
     * Catch execution of Logger.log in the context of execution flow of any LoggerTest method;
     * 
     * @param pjp is "reserved stuff" here, aspectj knows about use of "around advice" and
     * will provide method with {@link ProceedingJoinPoint} object on runtime.
    */
    @Around(value = "cflow(within(LoggerTest)) &amp;amp;&amp;amp; execution(void Logger.log(..))")
    public void adviceMethod(final ProceedingJoinPoint pjp) throws Exception {
        executor.execute(new Runnable() {
        public void run() {
            try {
                System.out.println("[" + Thread.currentThread().getName() + "]: doing log()");
                // calling "trapped" execution join point;
                pjp.proceed();
               System.out.println("[" + Thread.currentThread().getName() + "]: done log()");
            } catch (Throwable ignore) {}
        }
        });
    }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;After weiving above logic into the code(at compilation time), we have following output: &lt;/span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; font-family: Verdana,sans-serif; text-align: center;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;a href="http://2.bp.blogspot.com/_pidCk5ODrPM/SyKrpRzwOWI/AAAAAAAABEU/Hy0brW5EArY/s1600-h/2.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_pidCk5ODrPM/SyKrpRzwOWI/AAAAAAAABEU/Hy0brW5EArY/s400/2.PNG" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;div style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;You see what have already happened?! Our sequential logging transparently became asynchronous! Logging have done in pool-1-thread-1, while our major flow proceeded in main without waiting for log operation. This is legal: log() is void and hasn't access to any shared state, also actual logging happens in the same order as it would in "normal" case(actually, this is true while the size of thread pool = 1 ;)).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;Lets examine "aspect" and respective AOP(aspect oriented programming) therms shortly.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;First of all, aspect roughly speaking could be mapped logically to a class, with annotation @Aspect(thanks to 5-th version of AspectJ), by default there is single aspect instance within class loader. Magic string "cflow(execution..." is a "pointcut", pointcut for java is like sql for db. Pointcut in AOP selects/matches/catches/fetches program's "join points"(while sql - rows in db). There are several types of join points: initialization of instance, static initialization of class(along with class members and static blocks), execution/call of a method/constructor and so on. So, join points are recognizable "points" in program! Recognizable by ajc.exe, aspectj compiler, which understands both java and aspectj code, because itself ajc is extension of javac. Last thing - adviceMethod()@Around - this is a routine wich will be called on aspect each time joint point is matched. Such routine is called "advice"(there are also another types of advice: @Before and @After). The reason why I chose @Around - because in this case aspectj provides me with ProceedingJoinPoint object(think of it as a trapped execution flow), and I have a choise: whether to proceed with catched join point calling ProceedingJoinPoin.proceed() or just skip it.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&lt;/span&gt; &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;There are a lot of what we should know about AOP and its java's implementation - AspecJ5.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;See these resources:&lt;a href="http://www.eclipse.org/aspectj/doc/released/progguide/index.html"&gt;The AspectJ Programming Guide&lt;/a&gt; &lt;a href="http://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html"&gt;The AspectJ 5 Development Kit Developer's Notebook&lt;/a&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;In case you want to start criticize such logging approach, I want &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;warn &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;you &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;against doing that, because core point of the post not in logging approach being used but in AOP possibilities.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;Thanks for your time!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/653496027060462681-1291698038748865302?l=artemv12.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/artemv12/~4/hku7ETMP1l8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://artemv12.blogspot.com/feeds/1291698038748865302/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://artemv12.blogspot.com/2009/12/proof-of-concept-doing-logging-in.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/1291698038748865302?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/653496027060462681/posts/default/1291698038748865302?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/artemv12/~3/hku7ETMP1l8/proof-of-concept-doing-logging-in.html" title="Proof-of-concept: log in separate thread, transparently with AspectJ5" /><author><name>artemv12</name><uri>http://www.blogger.com/profile/13734695625317422045</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://4.bp.blogspot.com/_pidCk5ODrPM/Sytr85MrQfI/AAAAAAAABEc/8CaZxo7GP6E/S220/ZEa6z.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_pidCk5ODrPM/SyKpTJw3NnI/AAAAAAAABEM/BXGFIJvfQgo/s72-c/1.PNG" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://artemv12.blogspot.com/2009/12/proof-of-concept-doing-logging-in.html</feedburner:origLink></entry></feed>

