<< updated maven to 2.1.0 | Home | how to synch iphone with thunderbird adress book >>

concurrency vs. synchronization

which way to go? synchronized? ConcurrentHashMap?

After getting up this morning I thought it would be good to contribute something back to my favorite ORM tool: iBATIS. I picked up IBATIS-508 and tried to create a unit test before applying the patch. Unfortunately I was not able to create one so I wanted to do at least some manual testing in order to find out in which way to fix the issue most efficiently. So I created a test case that compares different options for synchronizing access to a resource (namely a map) used by multiple threads at the same time.

The original issue was that the implementation of com.ibatis.common.beans.ClassInfo could cause performance problems under heavy load because of double synchronization. The implementation as of iBATIS 2.3.4 looks like this:

Obviously this is kind of redundant. I was not sure if I should apply the attached patch or just remove the synchronized clause. Therefore I created the test case that can be seen below. The results were:

No synchronization was fastest, with ConcurrentHashMap being also quite fast and the implementation as of 2.3.4 beeing the slowest. Therefore I decided to go for the patch originally attached to the issue. Please see bellow for the complete implementation of the test case. What are the results on your machine? Mine was a Dual Core T7500@2,2 GHZ with 3 GB Ram, Windows XP and Java 1.6.0_13

Please note that ConcurrentHashMap, unlike HashMap, does not allow null values for keys or values. This is not a problem in this use case, I just wanted to warn you.



Re: concurrency vs. synchronization

Cool! That will boost the performance of iBatis when synchronization is removed. And the only possible drawback is that the ClassInfo is created twice for a Class key.

Re: concurrency vs. synchronization

As Mike pointed out using a concurrent map implementation in this case may lead to non referential equal ClassInfo instances which can't be compared using ==. I see that as a non trivial change especially when dealing with public api. Out of curiousity I reran your tests locally and added a testcase for the high-scale-lib NonBlockingHashMap implementation. Intrestingly enough it performed slightly faster than the jdk ConcurrentHashMap on my machine.

Re: concurrency vs. synchronization

ClassInfo2 does not work as you could concurrently access the HashMap for different clazz'es which can break it.

Re: concurrency vs. synchronization

thanks for the comments. I don't think that duplicated ClassInfo classes are a problem. I doub't that anybody is using == on them. @frz: I was not aware that ClassInfo2 could break the HashMap. I thought concurrent access would be fine as long as the key is different between the different threads. Thanks for pointing this out!

Re: concurrency vs. synchronization

Somewhat late, but here are my results: impl. strategy: no synchronization avg calls per thread: 26.076.005 impl. strategy: synchronized block avg calls per thread: 6.120.937 impl. strategy: synchronized block + Collections.synchronizedMap avg calls per thread: 3.165.427 impl. strategy: Collections.synchronizedMap avg calls per thread: 6.860.422 impl. strategy: java5 ConcurrentHashMap avg calls per thread: 22.508.639 3.3GHz Dual Core. It's a nice CPU Benchmark ;)

Add a comment Send a TrackBack