Wednesday, October 7, 2009

Refactoring Sequential Java Code for Concurreny via Concurrent Libraries

With all of the talk about locks, threads, forks, and atomicity, the lessons being taught this semester in CS423, Operating System Design, with Dr. Sam King provide a reasonable understanding of the concepts discussed in this paper.

Atomicity is key when dealing with parallelism. In case you are not aware of the concept, atomicity can be thought of as a transaction on a database -- it either happens in its entirety without interruption or does not happen at all. No events from other threads can happen in between the start and stop of an atomic event.

As I was reading the paper, the first question to come to mind was how does a call to ConcurrentHashMap's putIfAbsent perform an update without locking the entire map? It is ideal for no updates to occur on an object, especially a queue or map, when being read or updated. The theory later came to light when it was identified only the part of the map being read or updated would be locked. The concept is fairly intriguing as I am not aware of it ever being done before quite that way. It means other threads could ideally continue to operate on other parts of the hash without interfering with other operations.

Why are there no atomic APIs in AtomicInteger for multiplication and division operators? Unfortunately, this answer was never explained. I wonder if it is because you may not end up with an integer as the result.

I greatly appreciate the consideration of not changing the original interface of a recursive method when converting to ForkJoinTask. Interfaces should not change and any change to the logic should be hidden from external clients. This is very critical when other systems depending on your system for a service expect that interface to always be there. Depending on the type system being impacted, a change to the interface could be very costly.

Concurrencer is more efficient and more accurate than refactoring by hand. Concurrencer produces the correct code in about 10 seconds and identified more opportunities for using the new, scalable APIs. Manual conversion is always error-prone. Having used refactoring tools in Eclipse, I am always hesitant about fully automating some manual actions. It would be wise to backup the current code into CVS or subversion before applying any automatic changes. After the changes are complete, you can do a diff to visually verify the changes are accurate. There will likely always that odd case where the automated tool did not know how to handle your code properly.

No comments:

Post a Comment