Category Archives: java

Oracle celebrates upcoming Java 7 release on video

Oracle recently celebrated the upcoming release of Java 7 with great pomp and show and subsequently made recordings of the event available as a series of videos available. If you haven’t already done so watch the videos in order below and read the blog post. There are also some thoughts on what’s upcoming in Java 8 in the final Q&A video.

It’s great to see Oracle engaging with the community to this extent and so publicly. This could have been just another release but I’m glad it received more publicity and visibility in this way, particularly, giving sub-project leads within Java 7 the recognition they deserve and the inspiration to carry on doing their great work I hope. I’ve also subscribed to the Oracle Java Magazine to see what it offers in due time.

Introducing Java 7: Moving Java Forward

Technical breakout sessions

In addition to the main presentation there were also smaller and more specialised technical breakout sessions as below.

Making Heads and Tails of Project Coin, Small Language Changes in JDK 7 (slides)

Divide and Conquer Parallelism with the Fork/Join Framework (slides)

The New File System API in JDK 7 (slides)

A Renaissance VM: One Platform, Many Languages (slides)

Meet the Experts: Q&A and Panel Discussion

Thoughts

A few thoughts that occurred to me having watched the above presentations follow below.

  • In Joe’s presentation I realised just how important good editor support is to prompt developers to adopt the project coin proposals over older ways of achieving the same ends. I was very impressed watching Netbeans detecting older syntax, prompting the developer through providing helpful warnings and being able to change old to new syntax instantaneously. I really hope Eclipse does the same. Eclipse has asked for quick fix, refactoring and template suggestions and in response to that I would say the most important incorporations above supporting the language would be supporting idiomatic transitions from Java 6 and Java 7.
  • Watching Joe Darcy go through how they implemented switch on strings and the associated performance considerations was fascinating. They actually use the hashcode values of strings to generate offsets and then use the offsets to execute the logic in the original case statements.
  • I found it very cool that Stuart Marks actually retrofitted the existing JDK code to utilise some of the Project Coin features not by hand but in an automated fashion. Apparently the JDK team also used annotation based processing and netbeans based tooling to help them upgrade the JDK codebase to use the new features.

Java 7 release candidate 1 released

Java 7 release candidate 1 has been released. Those people who thought Java 7 final would be released today (7th) – that is not the case as I mentioned in my previous post. It is simply being launched from a marketing standpoint. It will in fact be released as announced originally on 28 July. The real question now is how long before it gets to production for all of us. Common banks. Show a little courage and adopt early.

Depth and breadth first tree traversal

A friend of mine mentioned depth and breadth first tree traversal today and since I didn’t have a post on this already I thought this would be a good opportunity to do one and post my take on it. This focuses more on depth and breadth first tree traversal as opposed to graph search and whereas the algorithm is identical to how you’d expect an iterative dfs/bfs traversal to be there are a couple of small differences in the way I’ve done it here which may be serve as useful tips.

Node

The first thing we need is the classic Node class which has an identity and children.

package name.dhruba.kb.algos.dfsbfs;

class Node {

  final String name;
  final Node[] children;

  Node(String name) {
    this.name = name;
    this.children = new Node[0];
  }

  Node(String name, Node[] children) {
    this.name = name;
    this.children = children;
  }

  boolean hasChildren() {
    return children != null && children.length > 0;
  }

  @Override
  public String toString() {
    return name;
  }

}

Depth and breadth first traversal

Now here is the depth and breadth first traversal algorithm. Observations on the code follow underneath.

package name.dhruba.kb.algos.dfsbfs;

import java.util.ArrayDeque;
import java.util.Deque;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class DfsBfsTraverser {

    static final Logger logger = LoggerFactory.getLogger(DfsBfsTraverser.class);

    enum TraversalType {
        DEPTH_FIRST, BREADTH_FIRST;
    }

    interface NodeProcessor {
        void process(Node node);
    }

    static void traverse(Node root, TraversalType traversalType,
            NodeProcessor processor) {

        if (root == null) {
            return;
        }

        if (!root.hasChildren()) {
            processor.process(root);
            return;
        }

        Deque<Node> deck = new ArrayDeque<Node>();

        addToDeck(deck, traversalType, root);

        while (!deck.isEmpty()) {

            Node current = deck.removeFirst();

            if (current.hasChildren()) {
                for (Node child : current.children) {
                    addToDeck(deck, traversalType, child);
                }
            }

            try {
                processor.process(current);
            } catch (Exception e) {
                logger.error("error processing node", e);
            }

        }

    }

    static void addToDeck(Deque<Node> deck, TraversalType traversalType,
            Node node) {
        if (traversalType == TraversalType.DEPTH_FIRST) {
            deck.addFirst(node);
        } else {
            deck.addLast(node);
        }
    }

}

Observations

  • Note that the iterative algorithm implementation for depth and breadth first traversal are so similar that there’s no need to do a separate one for each. This class has quite easily been modified very subtly to accommodate both.
  • Note the use of ArrayDeque as a highly efficient stack confined deque. This allows us to add both to the front and back depending on the traversal type. It is also important to note that this class is likely to be faster than Stack when used as a stack, and faster than LinkedList when used as a queue as mentioned in its javadocs.
  • Note the initial elimination cases where we can get away with doing the bare minimum.
  • And finally note the use of a callback which allows the caller to do as they wish. This may seem like a small measure now but in the next post on this subject I’ll go into how to use the callback to allow the caller to dictate how far and in which direction they want to traverse based on the return value of the callback as well as how to allow the caller to terminate the traversal when they’ve found what they’re looking for. Such functionality can be critrical to good performance.

Testing

Take the following tree as an example.

       a
     /   
   b      c
 /      /  
e     f g    h

DFS returns: [a, c, h, g, b, f, e]
BFS returns: [a, b, c, e, f, g, h]

Note that DFS progresses from right to left due to the order in which children are added and removed from the deque.

Thanks for reading.

Java SE 7 API Javadocs receive new colour scheme

The Java SE 7 API specification (colloquially known as javadocs) have received a stylistic facelift. Compare v7 with v6. What do you think? Do you think it’s an improvement? Do you think it was even necessary? My opinion is twofold.

Firstly, although overall the javadocs appear to look nicer and more professional and corporate (as opposed to academic), when it comes to the method specifications, they aren’t as visually prominent as they were before due to the styles and colours overwhelming the text. In this respect both the styles and the colour of the text are subtle making them more difficult to tell apart. It’s not as clear as bold blue on white as it was before. This means that the reader will probably have to start reading the text to tell methods apart instead of just glancing at the visual image which was previously quite striking. A friend of mine also mentioned that there was just too much going on in terms of boxes too and I can see what he means.

Secondly and this is the more important point – if at all they had decided to spend time on enhancing the javadocs what required the most attention was in fact the navigability and searchability. The activity that takes up most of my time when using javadocs is finding the pieces of information i’m interested in. Better indexing and type ahead retrieval for classes, packages, properties and methods would be immensely useful rather than relying on the browser multiframe search which can fail at times by searching in the wrong frame. And before anyone mentions this I’m aware that there are third party sites which do such indexing and retrieval but I want this officially. So, that’s my 2p Oracle. I appreciate the time you’ve put in to the Javadocs but there’s much more room for improvement. Being a purist I really feel that, with this, it is more about content and usability than it is about appearance.

P.S. I think the new Google dark colour scheme and navigation bar is absolutely horrid. I want the old google back! 🙁

Concurrency pattern: Concurrent multimaps in Java

Preamble

Maintaining state is one of the most important ways in which we can increase the performance of our code. I don’t mean using a database or some goliath system somewhere. I mean local memory caches. Often they can be more than adequate to allow us to maintain state and provide a dramatic improvement in performance.

Before I start with the content of this post, let me just state the obvious or at least what should be obvious if it isn’t already to you, which is that the whole domain of caching is an incredibly difficult and inexhaustible area of study and work which is why dedicated distributed cache providers have sprung up all over the place that companies normally resort to in favour of in-memory caches.

However there is often a combination of in-memory and distributed caches in use and this post focuses on one aspect of in-memory caches – concurrent multimaps in Java and this post is the resource that I wish I had when I was tackling this problem numerous times in the past. The post focuses exclusively on copy on write multimap implementations as that allows the read operation to be lock free which can be a significant advantage depending on what you want to do on read.

Singular value caches

When an in-memory cache is desired one always resorts to some kind of a map structure. And if you’re storing singular key value pairs then creating a cache can be as easy as picking a map implementation though you still have the check-then-act operation of checking whether a value exists and if so returning it otherwise populating it and returning it which can result in some blocking. Nonetheless these problems have already been solved a thousand times over out there now.

For example, Google Guava MapMaker, provides an excellent implementation of the memoization pattern for a cache as follows which is probably the most complex case of a simple singular key value pair cache.

package name.dhruba.kb.concurrency.mapmaker;

import java.util.concurrent.ConcurrentMap;

import com.google.common.base.Function;
import com.google.common.collect.MapMaker;

public class CacheWithExpensiveValues<K, V> {

    private final ConcurrentMap<K, V> cache = new MapMaker().makeComputingMap(new Function<K, V>() {
        @Override
        public V apply(K input) {
            return acquireExpensiveCacheValue();
        }
    });

    public V get(K key) { return cache.get(key); }
    private V acquireExpensiveCacheValue() { return null; }

}

This implementation, in concept similar to the memoization pattern put forward by Brian Goetz in Java Concurrency In Practice, guarantees that a value for a given key is only acquired/resolved once in total during the lifetime of the cache in the event that it hasn’t already been computed which can be very useful if creating/computing the value is an expensive call. Threads which request an uncomputed value while it is being computed wait until the computation already in progress is finished.

This can be said to be strongly consistent in its guarantees. If you are willing to compromise on the guarantees that a cache makes, making it a weakly consistent cache, you may be able to achieve faster performance in some cases by relying solely on atomic CAS operations.

Multi-value caches

A standard singular key value pair cache is fairly straightforward these days. But what happens if you suddenly realise that you actually need multiple values per key? There’s a little bit more to it than first meets the eye. If you are well informed about what’s out there – as a knee jerk reaction, you might immediately think of Google Guava multimaps and create something similar to the example below.

package name.dhruba.kb.concurrency.guava;

import java.util.List;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimaps;

public class MultiMapCacheExample<K, V> {

    private final ListMultimap<K, V> cache = Multimaps.synchronizedListMultimap(ArrayListMultimap
            .<K, V> create());

    public List<V> get(K k) {
        return cache.get(k);
    }

    public List<V> remove(K k) {
        return cache.removeAll(k);
    }

    public void put(K k, V v) {
        cache.put(k, v);
    }

    public boolean remove(K k, K v) {
        return cache.remove(k, v);
    }

}

However, the astute programmer, soon realises the inadequacies of such a solution. The synchronised wrapper pattern here is very similar to that utilised in the JDK in that it synchronises all the calls in the interface. Also, it synchronises the entirety of all the methods in the interface meaning that all paths through any given method will need to contend for and acquire a lock. To put it another way no paths of execution through any method are non-blocking.

As a result, this implementation is likely to perform very poorly under heavy concurrent load. There will be a lot of contention and the cache will only be able to serve one operation at a time. So where do we go from here? Googling didn’t bring much success on the subject of concurrent multimaps in Java when I was looking for what was out there already so I decided to explore this area from first principles. Below I present the process of iteratively developing an efficient concurrent multimap implementation and over the course of a few implementations – making it eventually as non-blocking as possible.

It’s interesting to read why Google Guava have not and will not implement a concurrent multimap though I’m not sure I agree. I think a couple of general purpose concurrent multimaps or at the very least a copy on write multimap would be of value to the public as I’ve seen this pattern quite a lot over the years. But admittedly it wouldn’t just be one implementation. It would need to support a range of backing collections.

Concurrent multimaps

In the following example implementations I present only the most important mutative calls in the map interface as they are the most challenging and the best calls for illustration. Bear in mind also when reading through the implementations the following design considerations.

  • Mutative versus an immutable copy on write approach
  • Size of critical sections and thereby the degree of blocking
  • Strongly consistent or weakly consistent in mutual exclusion guarantees
  • When removing the last value for a key should the multimap remove the key and associated empty collection?

Weakly consistent implementations are very common in the industry but are prone to interleaving. For example, if a put() is in progress and someone calls remove() on the key altogether then, after the remove has been invoked, the put() will put the key value association back in which may not be desirable at all. Or maybe put tries to add to a value collection that is now no longer referenced because the key has been removed. These methods should ideally be mutually exclusive and the final implementation achieves this quality. Though it is important to bear in mind that for certain use cases weakly consistent guarantees are acceptable and it is for you to say what is acceptable to your use case and what isn’t.

Fully blocking multimap

The fully blocking implementation is equivalent to the synchronised wrapper approach because it synchronises the entirety of all the methods. This is without doubt the poorest performing implementation though on the plus side it has minimal allocation unlike the copy on write implementations that follow.

Advantages
  • Strongly consistent.
  • Doesn’t allocate any more than it needs to (unlike the copy on write pattern).
Disadvantages
  • Very poor performance.
  • Uses a hashmap which isn’t thread safe so offers no visibility guarantees.
  • All calls – reads/writes are blocking.
  • All paths through the blocking calls are blocking.
package name.dhruba.kb.concurrency.multimap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FullyBlockingMutativeArrayListMultiMap<K, V> {

    private final Map<K, List<V>> cache = new HashMap<K, List<V>>();

    public synchronized List<V> get(K k) {
        return cache.get(k);
    }

    public synchronized List<V> remove(K k) {
        return cache.remove(k);
    }

    public synchronized void put(K k, V v) {
        List<V> list = cache.get(k);
        if (list == null) {
            list = new ArrayList<V>();
            cache.put(k, list);
        }
        list.add(v);
    }

    public synchronized boolean remove(K k, V v) {
        List<V> list = cache.get(k);
        if (list == null) {
            return false;
        }
        if (list.isEmpty()) {
            cache.remove(k);
            return false;
        }
        boolean removed = list.remove(v);
        if (removed && list.isEmpty()) {
            cache.remove(k);
        }
        return removed;
    }

}

Copy on write multimap using synchronisation

This is an initial implementation of a copy on write approach but without using the jdk copy on write collections. It is strongly consistent but it still synchronises too much on writes.

Advantages
  • Strongly consistent.
  • Uses concurrent hash map so we can have non-blocking read.
Disadvantages
  • The synchronisation lock blocks on the entire cache.
  • The blocking calls are entirely blocking so all paths through them will block.
  • Concurrent hash map is blocking itself although at a fine grained level using stripes.
package name.dhruba.kb.concurrency.multimap;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class CopyOnWriteArrayListMultiMap<K, V> {

	private final ConcurrentMap<K, List<V>> cache = new ConcurrentHashMap<K, List<V>>();

	public List<V> get(K k) {
		return cache.get(k);
	}

	public synchronized List<V> remove(K k) {
		return cache.remove(k);
	}

	public synchronized void put(K k, V v) {
		List<V> list = cache.get(k);
		if (list == null || list.isEmpty()) {
			list = new ArrayList<V>();
		} else {
			list = new ArrayList<V>(list);
		}
		list.add(v);
		cache.put(k, list);
	}

	public synchronized boolean remove(K k, K v) {
		List<V> list = cache.get(k);
		if (list == null) {
			return false;
		}
		if (list.isEmpty()) {
			cache.remove(k);
			return false;
		}
		boolean removed = list.remove(v);
		if (removed) {
			if (list.isEmpty()) {
				cache.remove(k);
			} else {
			    list = new ArrayList<V>(list);
				cache.put(k, list);
			}
		}
		return removed;
	}

}

Copy on write multimap but using the JDK CopyOnWriteArrayList

Here we opt to use the copy on write array list from the jdk. There is no synchronisation in the class itself (only within backing structure) but it is dangerously prone to interleaving and therefore weakly consistent. Personally I wouldn’t be happy about put() and remove() not being mutually exclusive and interleaving through each other. That to me would be unacceptable. Amazingly I’ve seen this implementation all too often at work.

Advantages
  • Uses {@link ConcurrentHashMap} for thread safety and visibility.
  • Uses {@link CopyOnWriteArrayList} for list thread safety and visibility.
  • No blocking in class itself. Instead the backing jdk classes handle blocking for us.
  • Blocking has been reduced to key level granularity instead of being at the cache level.
Disadvantages
  • Prone to interleaving. It is weakly consistent and does not guarantee mutually exclusive and atomic calls. The {@link remove(K)} call can interleave through the lines of the put method and potentially key value pairs can be added back in if a{@link remove(K)} is called part way through the {@link #put(K,V)} call. To be strongly consistent the {@link #remove(K)} and {@link #put(K,V)} need to be mutually exclusive.
package name.dhruba.kb.concurrency.multimap;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;

public class JdkCopyOnWriteArrayListMultiMap<K, V> {

    private final ConcurrentMap<K, List<V>> cache = new ConcurrentHashMap<K, List<V>>();

    public List<V> get(K k) {
        return cache.get(k);
    }

    public List<V> remove(K k) {
        return cache.remove(k);
    }

    public void put(K k, V v) {
        List<V> list = cache.get(k);
        if (list == null) {
            list = new CopyOnWriteArrayList<V>();
            List<V> oldList = cache.putIfAbsent(k, list);
            if (oldList != null) {
                list = oldList;
            }
        }
        list.add(v);
    }

    public boolean remove(K k, K v) {
        List<V> list = cache.get(k);
        if (list == null) {
            return false;
        }
        if (list.isEmpty()) {
            cache.remove(k);
            return false;
        }
        boolean removed = list.remove(k);
        if (removed && list.isEmpty()) {
            cache.remove(k);
        }
        return removed;
    }

}

Partially blocking copy on write multimap

So from the previous implementation we return to a strongly consistent implementation but this time block only on certain paths through the put() and remove() methods at the cost of a little additional allocation. However the lock it uses is still a global one which means that operations on different keys will become sequential which is obviously not desirable.

Advantages
  • Strongly consistent.
  • Use of {@link ConcurrentHashMap} for thread safety and visibility guarantees.
  • The {@link #get(Object)} and {@link #remove(Object)} calls don’t block at all in this class.
  • The {@link #put(Object, Object)} and {@link #remove(Object, Object)} methods do block but only for certain paths. There are paths through these methods which won’t block at all. The {@link #put(Object, Object)} method only blocks if the {@link ConcurrentHashMap#putIfAbsent(Object, Object)} fails and the {@link #remove(Object, Object)} only blocks if there is something there to remove.
Disadvantages
  • We allocate a list initially in the {@link #put(Object, Object)} which may not be needed.
  • {@link ConcurrentHashMap} still blocks although at a finer level using stripes.
  • The blocking synchronisation we are using is still blocking the entire cache. What we really want is to block only the keys that hash to the value bucket that we are currently working with. A more fine grained blocking strategy is called for which we’ll see in the next implementation.
package name.dhruba.kb.concurrency.multimap;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class PartiallyBlockingCopyOnWriteArrayListMultiMap<K, V> {

    private final ConcurrentMap<K, List<V>> cache = new ConcurrentHashMap<K, List<V>>();

    public List<V> get(K k) {
        return cache.get(k);
    }

    public List<V> remove(K k) {
        synchronized (cache) {
            return cache.remove(k);
        }
    }

    public void put(K k, V v) {
        List<V> list = Collections.singletonList(v);
        List<V> oldList = cache.putIfAbsent(k, list);
        if (oldList != null) {
            synchronized (cache) {
                list = cache.get(k);
                if (list == null || list.isEmpty()) {
                    list = new ArrayList<V>();
                } else {
                    list = new ArrayList<V>(list);
                }
                list.add(v);
                cache.put(k, list);
            }
        }
    }

    public boolean remove(K k, K v) {
        List<V> list = cache.get(k);
        if (list == null) {
            return false;
        }
        synchronized (cache) {
            list = cache.get(k);
            if (list == null) {
                return false;
            }
            if (list.isEmpty()) {
                cache.remove(k);
                return false;
            }
            boolean removed = list.remove(v);
            if (removed) {
                if (list.isEmpty()) {
                    cache.remove(k);
                } else {
                    list = new ArrayList<V>(list);
                    cache.put(k, list);
                }
            }
            return removed;
        }
    }

}

Striped lock copy on write multimap

The final implementation – strongly consistent, non-blocking backing structure, fine grained locking at key level and locking only on necessary paths. This example uses a striped lock provider. It’s purpose is to take a key as input and provide a lock as output to lock on. However it is consistent in that it always provides the same lock for the same key guaranteeing the mutual exclusion that is necessary.

It takes the number of locks desired as a constructor input (by default 2048) which means we can decide how many locks we want to make available in the distribution. It will then accordingly consistently hash across the distribution of locks. It also provides a better key distribution over non-concurrent hash maps. The concept behind the striped lock provider and its implementation is a very interesting topic and this will form a new post of its own in the future! Stay tuned!

Advantages
  • Strongly consistent. Implements correct mutual exclusion of calls.
  • Uses {@link NonBlockingHashMap} instead of {@link ConcurrentHashMap} so the backing cache member does not block at all. Far more efficient and scalable than {@link ConcurrentHashMap}.
  • The read calls are completely non-blocking even at the cache structure level.
  • The {@link #put(Object, Object)} and {@link #remove(Object, Object)} methods do block but only for certain paths. There are paths through these methods which won’t block at all. The {@link #put(Object, Object)} method only blocks if the {@link NonBlockingHashMap#putIfAbsent(Object, Object)} fails and the {@link #remove(Object, Object)} only blocks if there is something there to remove.
  • And to save the best for last – there is no longer any blocking at the cache level. We now apply mutual exclusion only at the key level.

This implementation has the best of all worlds really as long as the copy on write approach is acceptable to you.

Disadvantages
  • Fundamentally being a copy on write approach it does more allocation than a mutative approach.
package name.dhruba.kb.concurrency.multimap;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import name.dhruba.kb.concurrency.striping.IntrinsicStripedLockProvider;

import org.cliffc.high_scale_lib.NonBlockingHashMap;

public class StripedLockArrayListMultiMap<K, V> {

    private final IntrinsicStripedLockProvider stripedLockProvider = new IntrinsicStripedLockProvider();
    private final ConcurrentMap<K, List<V>> cache = new NonBlockingHashMap<K, List<V>>();

    public List<V> get(K k) {
        return cache.get(k);
    }

    public List<V> remove(K k) {
        Object lock = stripedLockProvider.getLockForKey(k);
        synchronized (lock) {
            return cache.remove(k);
        }
    }

    public void put(K k, V v) {
        List<V> list = Collections.singletonList(v);
        List<V> oldList = cache.putIfAbsent(k, list);
        if (oldList != null) {
            Object lock = stripedLockProvider.getLockForKey(k);
            synchronized (lock) {
                list = cache.get(k);
                if (list == null || list.isEmpty()) {
                    list = new ArrayList<V>();
                } else {
                    list = new ArrayList<V>(list);
                }
                list.add(v);
                cache.put(k, list);
            }
        }
    }

    public boolean remove(K k, K v) {
        List<V> list = cache.get(k);
        if (list == null) {
            return false;
        }
        Object lock = stripedLockProvider.getLockForKey(k);
        synchronized (lock) {
            list = cache.get(k);
            if (list == null) {
                return false;
            }
            if (list.isEmpty()) {
                cache.remove(k);
                return false;
            }
            boolean removed = list.remove(v);
            if (removed) {
                if (list.isEmpty()) {
                    cache.remove(k);
                } else {
                    list = new ArrayList<V>(list);
                    cache.put(k, list);
                }
            }
            return removed;
        }
    }

}

Conclusion

When designing concurrent structures it is important not to always resort blindly to what’s out there and for custom concurrent data structures there will be no ready made solution. For those cases concurrent patterns such as this are invaluable and best practices such as reducing critical sections, reducing the amount of blocking to paths that need it, reducing the granularity of the locks being used and selection of the right backing structures are absolutely key to an efficient concurrent data structure. If you have any feedback for how to do better on the above or if I’ve made any mistakes please do let me know. Enjoy and thanks for reading.

Links

FYI – it seems Joe Kearney has done an alternative implementation that does not rely on copy on write.

Update [05/07/2011]: Code updated with bug fixes for edge cases.
Update [17/04/2013]: After a long wait I finally fixed the bug that Charlie reported below. Thanks Charlie!

API Pattern: Exception transformer

Exception transformation is an API pattern that I came across some time back, originally from an able colleague of mine, that although very simple has proved to be immensely useful to me on a couple of occasions. Checked exceptions are widespread in Java. Imagine the situation where you are calling numerous methods on a class (say for the sake of serving as an example: a service class) each of which throws a checked exception (say ServiceException).

Service class that throws checked exceptions

package name.dhruba.kb.patterns.exceptions;

class Service {

    static class ServiceException extends Exception {}

    void serviceMethod1() throws ServiceException {}
    void serviceMethod2() throws ServiceException {}

}

Client with repetitive error handling logic

Your class as a client now has to deal with this exception every time you call a service method and also for every different method you call.

package name.dhruba.kb.patterns.exceptions;

import name.dhruba.kb.patterns.exceptions.Service.ServiceException;

class Client {

    private Service service;

    void callServiceMethod1Normally() {
        try {
            service.serviceMethod1();
        } catch (ServiceException e) {
            throw new RuntimeException("calling service method 1 failed", e);
        }
    }

    void callServiceMethod2Normally() {
        try {
            service.serviceMethod2();
        } catch (ServiceException e) {
            throw new RuntimeException("calling service method 2 failed", e);
        }
    }

}

Exception transformer abstraction

However your exception handling strategy may be the same across your use of the service class only with a different message each time. Instead of repetitively duplicating your exception handling logic (try/catch) around every service call you can abstract this out as follows. The following class abstracts the logic out. Note that this class is only shown as a separate class for the purposes of incrementally describing the pattern. For best effect this class should ideally be contained within your client class as a static inner class.

package name.dhruba.kb.patterns.exceptions;

import name.dhruba.kb.patterns.exceptions.Service.ServiceException;

abstract class ExceptionTransformer {

    abstract void call() throws ServiceException;

    void transform(String message) {
        try {
            call();
        } catch (ServiceException e) {
            throw new RuntimeException(message, e);
        }
    }

}

New client using exception transformer

Now using the new exception transformer our exception handling logic is simplified to only the logic that differs between the client methods.

package name.dhruba.kb.patterns.exceptions;

import name.dhruba.kb.patterns.exceptions.Service.ServiceException;

class ClientUsingExceptionTransformer {

    private Service service;

    void callServiceMethod1UsingTransformer() {
        new ExceptionTransformer() {
            @Override
            void call() throws ServiceException {
                service.serviceMethod1();
            }
        }.transform("calling service method 1 failed");
    }

    void callServiceMethod2UsingTransformer() {
        new ExceptionTransformer() {
            @Override
            void call() throws ServiceException {
                service.serviceMethod2();
            }
        }.transform("calling service method 2 failed");
    }

}

Variations

This pattern can be easily varied to suit your personal exception handling styles. Here’s another variation where different checked exceptions are thrown by different service methods and handled by only logging them this time.

package name.dhruba.kb.patterns.exceptions;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class ClientWithVariations {

    static final Logger logger = LoggerFactory.getLogger(ClientWithVariations.class);

    static class Service {

        static class ServiceHungry extends Exception {}
        static class ServiceSleepy extends Exception {}

        void hungryMethod() throws ServiceHungry {}
        void sleepyMethod() throws ServiceSleepy {}

    }

    private Service service;

    void callHungryMethod() {
        new ExceptionTransformer() {
            @Override
            void call() throws Exception {
                service.hungryMethod();
            }
        }.transform("method was too hungry to respond :(");
    }

    void callSleepyMethod() {
        new ExceptionTransformer() {
            @Override
            void call() throws Exception {
                service.sleepyMethod();
            }
        }.transform("method was too sleepy to respond :(");
    }

    static abstract class ExceptionTransformer {

        abstract void call() throws Exception;

        void transform(String message) {
            try {
                call();
            } catch (Exception e) {
                logger.error(message, e);
            }
        }

    }

}

This pattern really shows its value most effectively when you have numerous methods using it and also when there are multiple checked exceptions to handle resulting in multiple catch blocks all over the place.

Do you have any exception handling API patterns of your own? I know Joshua Bloch has suggested a few in Effective Java of which one comes to mind – an exception throwing method can be transformed into a boolean via another method which just returns false in the catch block and true elsewhere that can be quite useful if you don’t want to pollute the rest of the code with knowledge of this handling logic. By the way, before anyone mentions this I’m not suggesting converting checked exceptions to runtime exceptions or suppressing them by logging them is always the right thing to do. Thanks for reading.

P.S. This pattern will be particularly nice with closures in Java 8. And the multicatch in Java 7 will certainly also help make code more concise.

JDK7 Project Coin Primer

Although I knew about the small language enhancements going into JDK7, named Project Coin, quite some time back it was only today that I got around to actually coding and trying them all out primarily due to prior laziness and poor editor support. Yes I know – there’s plenty of docs on Project Coin out there already. This is mine.

And now that JDK7 actually has a finite number of steps in its release schedule and is scheduled for release on 28/07/2011 we know our efforts in learning the new feature set are not going to waste and that very soon we’ll be able to write production code with this knowledge to make the industry a better place which is ultimately what is important.

Here I present a quick primer for the uninitiated. The small language enhancements going into JDK7 are as follows.

  1. Strings in switch
  2. Binary integral literals
  3. Underscores in numeric literals
  4. Multi-catch and more precise rethrow
  5. Improved type inference for generic instance creation(diamond)
  6. try-with-resources statement
  7. Simplified varargs method invocation

Below I provide one example per feature that will take you through each feature in a flash.

Strings in switch

A long overdue and seemingly basic feature but better late than never.

package name.dhruba.kb.jdk7;

public class StringsInSwitch {

    public static void main(String[] args) {
        for (String a : new String[]{"foo", "bar", "baz"}) {
            switch (a) {
                case "foo":
                    System.out.println("received foo!");
                    break;
                case "bar":
                    System.out.println("received bar!");
                    break;
                case "baz":
                    System.out.println("received baz!");
                    break;
            }
        }
    }
    
}

Binary integral literals

I can’t say I’ve ever felt the absence of this rather unusual feature. Though it seems it was felt compelling enough to be added in. This is primarily a readability advantage – a semantic representation.

package name.dhruba.kb.jdk7;

public class BinaryLiterals {

    public static void main(String[] args) {

        // An 8-bit 'byte' literal.
        byte aByte = (byte) 0b00100001;

        // A 16-bit 'short' literal.
        short aShort = (short) 0b1010000101000101;

        // Some 32-bit 'int' literals.
        int anInt1 = 0b10100001010001011010000101000101;
        int anInt2 = 0b101;
        int anInt3 = 0B101; // The B can be upper or lower case.

        // A 64-bit 'long' literal. Note the "L" suffix.
        long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;

    }
    
}

Underscores in numeric literals

I’ve often found myself adding javadoc to make a constant declaration clearer. This makes them somewhat clearer which is definitely helpful.

package name.dhruba.kb.jdk7;

public class UnderScoredLiterals {

    public static void main(String[] args) {

        long creditCardNumber = 1234_5678_9012_3456L;
        long socialSecurityNumber = 999_99_9999L;
        float pi = 3.14_15F;
        long hexBytes = 0xFF_EC_DE_5E;
        long hexWords = 0xCAFE_BABE;
        long maxLong = 0x7fff_ffff_ffff_ffffL;
        byte nybbles = 0b0010_0101;
        long bytes = 0b11010010_01101001_10010100_10010010;

    }
    
}

Multi-catch

The multi-catch is very useful indeed and significantly reduces the number of lines of code to do such things from before.

package name.dhruba.kb.jdk7;

public class MultiCatchException {

    static class Exception1 extends Exception {}
    static class Exception2 extends Exception {}

    public static void main(String[] args) {
        try {
            boolean test = true;
            if (test) {
                throw new Exception1();
            } else {
                throw new Exception2();
            }
        } catch (Exception1 | Exception2 e) {
        }
    }
    
}

More precise exception rethrow

The more precise rethrow is a tricky one to understand. See if you can spot what the new feature is in the example below. Will it compile on pre-java-7? If not how would it need to be changed to compile on pre-java-7? The answers lie after the example.

package name.dhruba.kb.jdk7;

public class MorePreciseExceptionRethrow {

    static class Exception1 extends Exception {}
    static class Exception2 extends Exception {}
    
    public static void main(String[] args) throws Exception1, Exception2 {
        try {
            boolean test = true;
            if (test) {
                throw new Exception1();
            } else {
                throw new Exception2();
            }
        } catch (Exception e) {
            throw e;
        }
    }
    
}

On Java 6 compiling the above gives the following exception.

Foo.java:18: unreported exception java.lang.Exception; must be caught or declared to be thrown
            throw e;
            ^
1 error

This can be fixed for Java 6 by changing:

public static void main(String[] args) throws Exception1, Exception2 {

to:

public static void main(String[] args) throws Exception {{

So now you see the improvement that Java 7 offers with this feature. You can be more precise in the declaration of the exceptions that you rethrow. Very nice indeed.

Improved type inference for generic instance creation(diamond)

Oh my God. Thank you Oracle for this feature. I breathe a huge sigh of relief. How long has it taken to get this out? How many keystrokes and keyboards have I wasted over the period of my career? And how much of a penalty have the tips of my fingers paid over the years for typing out the right hand side of a generic assigment? This curse is no more. Particularly note the constructor inference which is new to Java 7 also.

package name.dhruba.kb.jdk7;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GenericDiamondTypeInference {
 
    static class MyClass <X> {
        <Y> MyClass(Y y) {
        }
    }
    
    public static void main(String[] args) {
        
        // constructor inference
        // <X> = <Integer>, <Y> = <String>
        MyClass<Integer> myClass1 = new MyClass<>("");
        
        // standard stuff
        List<String> list = new ArrayList<>();
        Map<String, List<String>> map = new HashMap<>();
        
    }
    
}

try-with-resources statement

This is simply beautiful and incredibly reassuring for the simple reason that resource closing is not only automatic and requires a lot less code but if in the examples below multiples exceptions are thrown (i.e. one in the closing of the resource and one in the use of the resource) then not only does the latter not get swallowed (unlike pre-java-7) but finally you can access all suppressed exceptions (i.e. the former) via the new API.

package name.dhruba.kb.jdk7;

public class TryWithResources {

    static class MyResource1 implements AutoCloseable {
        @Override
        public void close() throws Exception {
            System.out.println("MyResource1 was closed!");
        }
    }
    
    static class MyResource2 implements AutoCloseable {
        @Override
        public void close() throws Exception {
            System.out.println("MyResource2 was closed!");
        }
    }


    public static void main(String[] args) throws Exception {
        /*
         * close() methods called in opposite order of creation
         */
        try (MyResource1 myResource1 = new MyResource1();
             MyResource2 myResource2 = new MyResource2()) {}
    }
    
}

NOTE: In the above example the resources are closed in an order opposite to their order of creation.

Simplified varargs method invocation

This was a very tricky one to investigate. It’s still not clear what ‘simplified varargs method invocation’ is referring to but one difference (improvement) I was able to narrow down was that of a more specific and helpful warning that jdk7 adds to certain varargs code as below.

package name.dhruba.kb.jdk7;

import java.util.Collections;
import java.util.List;
import java.util.Map;

public class BetterVarargsWarnings {

    static <T> List<T> foo(T... elements) {
        return null;
    }

    static List<Map<String, String>> bar() {
        Map<String, String> m = Collections.singletonMap("a", "b");
        return foo(m, m, m);
    }

}

In Java 6 the above generates the following warning.

/Users/dhruba/NetBeansProjects/SwitchTest/src/name/dhruba/kb/jdk7/BetterVarargsWarnings.java:15: warning: [unchecked] unchecked generic array creation of type java.util.Map<java.lang.String,java.lang.String>[] for varargs parameter
        return foo(m, m, m);
                  ^
1 warning

In Java 7 however an additional warning is generated.

/Users/dhruba/NetBeansProjects/SwitchTest/src/name/dhruba/kb/jdk7/BetterVarargsWarnings.java:9: warning: [unchecked] Possible heap pollution from parameterized vararg type T
    static <T> List<T> foo(T... elements) {
                                ^
  where T is a type-variable:
    T extends Object declared in method <T>foo(T...)
/Users/dhruba/NetBeansProjects/SwitchTest/src/name/dhruba/kb/jdk7/BetterVarargsWarnings.java:15: warning: [unchecked] unchecked generic array creation for varargs parameter of type Map<String,String>[]
        return foo(m, m, m);
                  ^
2 warnings

Compiling Java 7

  • Download JDK7. I used OpenJDK OS X Build on my Mac.
  • Download Netbeans 7 which is what I used again on the Mac. Or Intellij 10.5.
  • Be happy. There’s no link for that but if you don’t feel this at this point you may want to think of a change of career.

Thanks to LingPipe for linking to this post.

jsr166y and extra166y libraries on Maven

If you wish to use jsr166y (fork join) and extra166y (parallel arrays), normally available as jars at the concurrency interest site, through maven there is a mirror repository that has been set up that can be used as follows.

Milestone repository

<repositories>
	<repository>
		<snapshots>
			<enabled>false</enabled>
		</snapshots>
		<id>codehaus-milestone</id>
		<name>codehaus-milestone</name>
		<url>http://repository.codehaus.org</url>
	</repository>
</repositories>

Dependencies

<dependency>
	<groupId>org.codehaus.jsr166-mirror</groupId>
	<artifactId>jsr166y</artifactId>
	<version>1.7.0</version>
</dependency>
<dependency>
	<groupId>org.codehaus.jsr166-mirror</groupId>
	<artifactId>extra166y</artifactId>
	<version>1.7.0</version>
</dependency>

Though bear in mind that fork join will be included in the eventual Java 7 release. Parallel arrays sadly won’t be but at least they are available separately.

Concurrency Pattern: The Producer Consumer Pattern in Java

Introduction

Recently, after a very long time, I encountered once again the topic of the producer consumer pattern in Java. In our day to day lives as developers we rarely have to implement such a pattern in code. We are usually dealing with producers and consumers in concept form at far higher level of abstractions such as inter-process level over MQ or 29 West or if it must be in-process normal method invocation might suffice. Or it may be that we only have to implement one half, either the producer or consumer, at our end and the other half is written by a downstream system that we are integrating with. I myself can’t remember the last time I had to write a literal in-process producer/consumer implementation for production.

Though one could argue that any message passing through queues or otherwise is a manifestation of this pattern but then if you continue along this route the message passing paradigm or even object orientation could be considered to represent this pattern. Okay I’ll stop here with the introduction as my philosophical side is taking over. But anyway, as I came across this recently I thought it an interesting exercise to explore and document the various ways of implementing such a pattern in Java. Employers also tend to have this as a favourite question to ask.

Problem Statement

The problem explored here is to implement the producer consumer pattern in Java to perform single message exchange without polling or spinning as these can be wasteful of resources. Though if you disagree that these can be wasteful please provide an appropriate performant implementation in the comments!

Solution

In any producer consumer scenario there are three entities – producer, consumer and broker. Though the broker is optional in certain topologies in real life such as 29West multicast – for the purposes of this post the broker is central to exploring the different ways of implementing this pattern. So let’s lay down the prerequisites.

Bootstrap

The bootstrap main method simply chooses a broker implementation, makes it available to the producer and consumer and starts the latter two as threads of their own. The broker is an interface to allow us to substitute in different implementations.

package name.dhruba.kb.concurrency.pc;

import name.dhruba.kb.concurrency.pc.broker.Broker;
import name.dhruba.kb.concurrency.pc.broker.ConditionWaitBroker;

public class ProducerConsumerBootstrap {

    public static void main(String[] args) {
        Broker<Integer> exchanger = new WaitNotifyBroker<Integer>();
        new Thread(new Producer(exchanger)).start();
        new Thread(new Consumer(exchanger)).start();
    }

}

Running the bootstrap should produce the following output.

produced: 0
consumed: 0
produced: 1
consumed: 1
produced: 2
consumed: 2
produced: 3
consumed: 3
produced: 4
consumed: 4
produced termination signal
received termination signal

Producer

The producer simply produces five integers starting at zero in sequence followed by a termination signal (-1).

package name.dhruba.kb.concurrency.pc;

import name.dhruba.kb.concurrency.pc.broker.Broker;

class Producer implements Runnable {

    final Broker<Integer> broker;

    Producer(Broker<Integer> exchanger) {
        this.broker = exchanger;
    }

    @Override
    public void run() {
        try {
            for (int i = 0; i < 5; i++) {
                broker.put(i);
                System.out.format("produced: %s%n", i);
                Thread.sleep(1000);
            }
            broker.put(-1);
            System.out.println("produced termination signal");
        } catch (InterruptedException e) {
            e.printStackTrace();
            return;
        }
    }

}

Consumer

The consumer, in turn, receives the five integers and terminates consumption upon receiving the termination signal.

package name.dhruba.kb.concurrency.pc;

import name.dhruba.kb.concurrency.pc.broker.Broker;

class Consumer implements Runnable {

    final Broker<Integer> broker;

    Consumer(Broker<Integer> broker) {
        this.broker = broker;
    }

    @Override
    public void run() {
        try {
            for (Integer message = broker.take(); message != -1; message = broker.take()) {
                System.out.format("consumed: %s%n", message);
                Thread.sleep(1000);
            }
            System.out.println("received termination signal");
        } catch (InterruptedException e) {
            e.printStackTrace();
            return;
        }
    }

}

Broker

The broker is the focus of this post. It is an interface as follows and its implementations are intended to support exchange of a single message at a time for simplicity of illustration.

package name.dhruba.kb.concurrency.pc.broker;

public interface Broker<T> {

    T take() throws InterruptedException;

    void put(T message) throws InterruptedException;

}

Broker implementations

Wait notify broker

A wait notify broker is possibly the simplest solution to the problem but also one at the lowest level of abstraction and also a legacy way. I cannot see any reason to use such primitives in the modern day and age to achieve any purpose. Joshua Bloch might say the same. Nevertheless the implementation would be as follows.

package name.dhruba.kb.concurrency.pc.broker;

public class WaitNotifyBroker<T> implements Broker<T> {

    private T message;
    private boolean empty = true;

    @Override
    public synchronized T take() throws InterruptedException {
        while (empty) {
            wait();
        }
        empty = true;
        notifyAll();
        return message;
    }

    @Override
    public synchronized void put(T message) throws InterruptedException {
        while (!empty) {
            wait();
        }
        empty = false;
        this.message = message;
        notifyAll();
    }

}
Synchronous Queue Broker

Having explored the rather boring wait-notify option we can now move onto more interesting implementations. The next thing that comes to mind is a SynchronousQueue. Why? Because the problem here is to facilitate single message exchange and for this SQ are perfect. Synchronous queues are effectively zero capacity queues and only pass messages across threads when consuming threads are ready to take handover.

    package name.dhruba.kb.concurrency.pc.broker;
    
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.SynchronousQueue;
    
    public class SyncQueueBroker<T> implements Broker<T> {
    
        private final BlockingQueue<T> queue = new SynchronousQueue<T>();
    
        @Override
        public T take() throws InterruptedException {
            return queue.take();
        }
    
        @Override
        public void put(T message) throws InterruptedException {
            queue.put(message);
        }
    
    }

In this example we could have used any blocking queue implementation but I used SQ for lightweight and immediate thread handovers without buffering.

Exchanger Broker

So far we’ve tackled wait-notify and queues but how else can we achieve the same effect. The next solution uses an Exchanger. The Exchanger is a little known but tremendously interesting and powerful utility to swap messages between threads in a really simple way. It’s usage is as follows.

package name.dhruba.kb.concurrency.pc.broker;

import java.util.concurrent.Exchanger;

public class ExchangerBroker<T> implements Broker<T> {

    private T message;
    private final Exchanger<T> exchanger = new Exchanger<T>();

    public void put(T message) throws InterruptedException {
        message = exchanger.exchange(message);
    }

    public T take() throws InterruptedException {
        return exchanger.exchange(message);
    }

}

I have to admit that I’ve never actually needed or found a legitimate use for an exchanger in production code and I’m curious to hear if you have.

Condition Broker

And, finally, we come to our last implementation using Condition which is again, like the Exchanger, little known and rarely seen out there (at least in my experience). I’ve only seen it in production code once and that too was for a very unusual use case. However conditions have a key advantage over their predecessor – wait/notify. To quote the javadoc on this one: “Condition factors out the Object monitor methods (wait, notify and notifyAll) into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitrary Lock implementations. Where a Lock replaces the use of synchronized methods and statements, a Condition replaces the use of the Object monitor methods”.

package name.dhruba.kb.concurrency.pc.broker;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionBroker<T> implements Broker<T> {

    private T message;
    private boolean empty = true;

    private final ReentrantLock lock = new ReentrantLock();
    private final Condition fullState = lock.newCondition();
    private final Condition emptyState = lock.newCondition();

    @Override
    public T take() throws InterruptedException {
        lock.lock();
        try {
            while (empty) {
                fullState.await();
            }
            empty = true;
            emptyState.signal();
            return message;
        } finally {
            lock.unlock();
        }
    }

    @Override
    public void put(T message) throws InterruptedException {
        lock.lock();
        try {
            while (!empty) {
                emptyState.await();
            }
            this.message = message;
            empty = false;
            fullState.signal();
        } finally {
            lock.unlock();
        }
    }

}

As you can see this is a much more effective semantic representation of the solution than the equivalent wait-notify.

Conclusion

The producer/consumer pattern is a useful scenario within which to explore solutions to bounded buffers, blocking queues and in-process eventing. Though it is usually of little use as higher level synchronisation primitives in Java 5 negate the need for us to implement any such thing in our processes. Employers love to ask this question in interviews. And for that bear in mind that it’s useful to know not only the higher level utilities but also the lower level wait notify behaviour even though it’s virtually obsolete at this point. If you can think of any other ways of implementing a single message exchange producer/consumer pattern please comment on here. Thanks.

Concurrency Pattern: Finding and exploiting areas of latent parallelism

With the JDK 7 developer preview out and a final release fast approaching it’s important to not only to become aware of what the new version offers but also, in certain areas where existing programming paradigms have radically changed, to make a mental shift in the way we think and understand how we can leverage these new paradigms best to our advantage. One such area is that of finding and exploiting areas of latent parallelism using a coarse grained parallelism approach.

As I mentioned in my previous post about the JDK7 developer preview being released – we’ve been using jsr166y and extra166y at work for some time now and this post really stems from an impassioned discussion that took place on finding and exploiting areas of latent parallelism in code so here’s what I have to say on the matter (inspired obviously by Doug Lea, Brian Goetz and my esteemed colleagues). The traditional and very much outdated mindset has only understood threads and ever since java 5 the executor framework on top. However this mechanism is fundamentally limited in its design in the extent of parallelism it can offer.

Firstly threads are expensive not only in their creation and stack size allocation but also in terms of context switching between them. Deciding on how many threads to have is also always at best an educated guess. A particular service within a process may decide to use all available cores but if every service in the process does the same then you have a disproportionately large number of threads and I have worked with applications with more than 150-200 threads operating at a time. Secondly, the executor framework has helped considerably in taking away some of the decision making from the developer and absorbing that complexity but it still suffers from heavy contention from multiple threads on the internal queue of tasks that it holds again adversely impacting performance. Thirdly, threads and executor frameworks normally do not scale up or down based on the hardware that they’re running on and certainly do not scale based on load. Their performance is very much constant by way of their underlying design.

Enter the fork join framework and parallel arrays. This is not a paragraph about how to use these new features but, in my opinion, a far more important note on how to rid ourselves of a legacy mindset on parallelism and make room for a new one. The fork join framework and parallel arrays (which are backed by the fork join framework and fork join pool internally) should not be perceived only as threading tools. That’s very dangerous as it means that we are only likely to use them in those areas where we previously used threads. They can in fact help us find and exploit areas of latent parallelism.

What does that mean? In all applications there are areas of code that operate sequentially. This code may be thread confined or stack confined and we almost never reconsider the way they perform. With FJ/PA we can now start making these areas concurrent. How is this an improvement? Well FJ/PA offer the following key features which makes them an ideal fit for such a use case.

Firstly, they are fundamentally decoupled from the number of threads in the way they add value which is a good thing. They tend to perform well regardless of how many threads they are using. Secondly, instead of using a single work queue for all threads they use one work queue per thread. This means further decoupling between threads and the way tasks are stored. Thirdly, given multiple work queues and multiple threads, FJ/PA perform work stealing. Every queue is a double ended queue and when one thread has completed all its tasks it then starts to process the tasks from the tail of another queue and because it is dequeuing off the tail there is no contention on the head of the queue from which the owner of the queue is dequeuing. Not only that but the largest tasks are placed towards the end of queues so that when another thread does steal work off another queue it gets enough work to effectively reduce the interval at which it steals again thereby again reducing contention. And finally, and most importantly, given a piece of FJ/PA code it will not only scale up but effectively scale down based not only on the hardware it runs but also on the load of the incoming work. When you understand this new paradigm suddenly the legacy paradigm seems so primitive and fundamentally stunted.

So the next time you are browsing your code consider using jsr166y and extra166y to find and exploit latent areas of parallelism. Generally the rule of thumb should be that this approach works best for operations that are cpu intensive and the legacy paradigm is better for io or network bound operations for obvious reasons. If operations are io or network bound there is less contention and the limitations of the legacy paradigm are less exposed. Don’t forget that the two libraries above can be used in java 6 so there’s no need to wait for java 7!