Wednesday, December 9, 2009

Concurrencey Utility: ReentrantReadWriteLock JSR 166

Concurrencey Utility: ReentrantReadWriteLock

1.5 onwards - package java.util.concurrent.locks

We have seen how to use synchronize keyword in method and in block of code. It is painstaking work that synchronizing the access of class level APIs and the object level using synchronize keyword. No guarantee of acquiring the lock in the order of thread arrived for wait queue.

JSR 166, comes with an approach which is similar to the synchronized mutual exclusive way of locking particular object. However, instead of acquiring the lock for the object (which will not allowed to access simultaneously), lock and granting work is given to the thirdparty. Means that which thread has to be allowed to access particular block of code, based on the operations(read/write).

ReentrantReadWriteLock RWL=new ReentrantReadWriteLock();
RWL.readLock().lock();
//do read operation -
RWL.readLock().unlock();

RWL.writeLock().lock();
//do write operation
RWL.writeLock().unlock();


Reentrant

Is this enough if we get guarantee in order of thread arrives to acquire the lock. Definitely not, we have to prioritize threads based on the business.

For instance, 100 different threads trying to access the block of code to make read only operation on the data, and waiting for the lock, now a thread comes with write operation. Will this thread will be waited long for other 100 threads to complete. No, write lock will highest priority of acquiring the lock and all other 100 threads(read lock) has to await to completion of last write lock.

Fairness

Not yet, ordering of read lock is guaranteed among the threads which are awaiting for read lock. How to order this sequence ?
Fairness option is introduced in concurrency utility, if we really interested in order, we have to pass 'true' as a value for fairness.

ReentrantReadWriteLock RWL=new ReentrantReadWriteLock(true);

Downgrading

If fair value set to true then performance will be degraded considerablly. How to tackle this issue, either minimizing the lock required block of code or downgrading the write lock based on need basis. For instance, Write lock acquiered for 10 lines of code, where as , write operation completes in 5th line, if we keep write lock upto 10th line then other writers also needs to wait, or if no write waiting for acquiring the lock then readers also needs to be waited. In 6th(after writeoperation) line of code, read lock acquired and write lock realeased then other writers can start doing the operation. This is called Downgrading. Keep in mind in this block of code , 9th line has read operation which possibly run after all the writer threads completed :(.

Note:
Can i acquire write lock within reader block ?
No, Within the writer block, we can acquire read lock, not vice-versa.

Why do i need to use read lock ?
Obsolutely, no need of read lock if your business logic not mandates to get very latest updated value. As I mentioned above, 100 readers has to wait for 1 wirter thread. If we are not introducing this reader lock then there could be possibility that 100 readers may get different values based on the order it get executes.

In my business 500 reader and rarely writer will occur, will reader lock cause any performance issue?
Not exactly, if no writer thread found in the given point of time then reader will not be blocked. Means, multiple reader(reader threads) can read at the same time. Read lock is used for getting writer threads changes immediate affect in all other reader threads.

Tuesday, December 8, 2009

Synchronized

Java: Synchronized

Every JAVA developer may be heard on and off about this word from JDK 1.0 . And, still there are lots of JAVA developers go with the myth.

JAVA is multithreaded language, where any block of code or any method can be run simultaneously by different Thread(s).

Synchronized keyword used in method signature to specify that this method can be run single thread at a time.

Is this enough to filter that all the thread in accessing particular method. No, we have to obtain lock for the particular resource, then only we can really implement filtering/preventing

simultaneous access.

Object lock : If synchronized keyword used in non-static methods in a class, then the object created from this class lets threads to access this method one by one on this object. For

instance, two object created from this class then T1 access obj1.getMethod() and T2 access obj2.getMethod(), this will run parallelly, since these two are different objects.

Class level Lock: If synchronized keyword used in stato method in a class then class level lock will be obtained. At a single point in time , only one static method can be accessed.

If I have a class with one static and another non-static method with synchronized keyword, then these two methods possibly run in parallel.

Above defined synchronized keyword helps in usecase of preventing simultaneous access of instance/class level variables. In real time, we are not required to block all the variable

access, and which will lead to get performance bottleneck. To avoid this mutex approach has to be used, means, that only the lockable object has to be locked instead of the whole

object and class level lock. For this synchronized block has used.

synchronized(this){
//do single threaded activity
}


The above code does the job equivalent to synchronized keyword in methods. However, this will perform better than the synchronized keyword, since the call waits after the context

switching of the method, but earlier method entry itself limited and filtered.


In the below code, static and non-statice present with synchronized keyword, and both method shares the same variable ind and almost all the time ind value as 20 in last line of

output. However, there could be possibility of getting some other number due to ind variable is not a volatile. I will explain in forthcoming blogs about volatile keyword.

public class Sync {
static int ind = 0;
public synchronized void wow() {
for (int i = 1; i <= 10; i++) {
System.out.println("hello " + ++ind);
try {
Thread.sleep(5);
} catch (Exception e) {
}
System.out.println("kris " + ind);
}

}

public static void wow1() {
for (int i = 1; i <= 10; i++) {
System.out.println("wow " + ++ind);
try {
Thread.sleep(5);
} catch (Exception e) {
}
System.out.println("d " + ind);
}
}

public static void main(String[] args) {
final Sync s = new Sync();
Thread t1 = new Thread() {
@Override
public void run()
wow1();
}
};

Thread t2 = new Thread() {
@Override
public void run() {
s.wow();
}
};

t1.start();
t2.start();

}
}



Additionally, If you want to test only object lock then in replace run method of T2 in T1.


Note:
1. synchronized keyword will not be used in constructor, since object creation will not be ever thread safe in JAVA.
2. Assume that 100 threads are trying to access the same synchronized block/method, no guarantee in order to get lock to run.
3. By calling wait() method, currently object lock holding thread can release the resource. Same thread will be try to acquire the lock if notify() or notifyAll() method in the same object

get called by the other RUNNING thread, which holds lock. No gurantee in order of which thread calls wait(), to obtain lock again.

java.util.concurrent package has the implementation to guarantee the order of the thread waits in obtaining lock for read and write.

@See java.util.concurrent.locks.ReentrantReadWriteLock

Monday, December 7, 2009

Collator : Locale sensitive String Comparison

If we wants to compare non-english characters for sorting, tabular then we do not have option to do that in normal string comparison(which will do straight away based on character to character comparison).

For Instance, I have Umlaut(ä, ë, ï and etc.,), if we compare with (au, eu, iu) then it will say both are different. But, in german/latin locale , these characters are equal respectively(au==ä). And additionally, 'ae' has to be treated by comparator as a single character.

From on, JDK 1.4 , java.text package introduced to get this job done.

Example from Sun JAVA DOC:

String Norwegian = "< a,A< b,B< c,C< d,D< e,E< f,F< g,G< h,H< i,I< j,J" +
"< k,K< l,L< m,M< n,N< o,O< p,P< q,Q< r,R< s,S< t,T" +
"< u,U< v,V< w,W< x,X< y,Y< z,Z" +
"< \u00E5=a\u030A,\u00C5=A\u030A" +
";aa,AA< \u00E6,\u00C6< \u00F8,\u00D8";
RuleBasedCollator myNorwegian = new RuleBasedCollator(Norwegian);


Please find more detail from Sun JAVADOC, which is nicely written with samples.

java.text.Collator.java
java.text.RuleBasedCollator.java

Recent Posts

Unix Commands | List all My Posts

Texts

This blog intended to share the knowledge and contribute to JAVA Community such a way that by providing samples and pointing right documents/webpages. We try to give our knowledege level best and no guarantee can be claimed on truth. Copyright and Terms of Policy refer blogspot.com