2013年5月27日 星期一

Conurrency 101 : Sychronizing Correctly

In this week, I want to ensure all guys know about some synchronizing skill.

DON'T DO:
1. Synchronizing on String:  

For example, we pass in a string "abcdef" created previously by: String xxx="abcdef"; into the function session, JVM would get the "abcdef" String Object in the String pool in Perm Gen. If there is more than one "abcdef" String in the String Pool. It may causes all String "abcdef" obtaining the lock, it may causes a lot of unexpected errors if there are also some critical sessions using "abcdef" as the synchronizer, causing race condition.


2. Synchronize on Numerical wrapper, like Integer(),Long(),Double() 

In fact, the JLS specified a certain range of number that always return the same instance when called. For example, It seems that two thread would be obtained their lock successfully, BUT, in fact, for sometime, threadOne or threadTwo would be blocked by chance as Integer one and Integer two are actually refer to the same instance in JVM Heap. For the above, I suggest to create a brand new Object to peform the locking. Like here: Object lock=new Object();

3.  Forget to do the Synchronize after using synchronized collections,like ConcurrentHashMap(), Collections.synchronizedMap(new HashMap())

By using these data structures, we can only ensure the thread Safety during get/put.
After we get the object from the data structure, you must use lock explicitly to ensure the thread safety issue.


DO: 1. Use JSR-166 Concurrent API. 
There are some concurrent API available after Java 5, they are CountDownLatches, CyclicBarrier, Semaphore..
List of API is as below: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html

2. Consider Lock API . 
Java has an API java.util.concurrent.locks that provides more features than synchronized. Statistically , it is more scalable than sychronized during high load.
Moreover, it provides a more flexible API and a provides a fair locking.

3. Use ArrayBlockQueue/LinkedBlockQueue/BlockDeque for Producer/Consumer pattern.
Please don't re-invent the wheel. Use the updated implementation from Java.
(LMAX Disruptor seems a more interested library recently. The Ring Buffer really makes it attractive for low latency dispatching/thread communication )

4. Follow the lock Sequence.
Avoid the deadlock.


This 101 would be updated when I have more ideas in mind.
Welcome everybody suggesting some pitfalls are required to beware for the Thread Safety.

沒有留言:

張貼留言