Sunday, 31 July 2016

Questions-
Re-entrant Locking-Why it come? What is problem with synchronize keyword.
Ans-
Let suppose one thread T1 is executing within a synchronized block and another thread T2 want to access the lock to execute same block. How T2 will know that someone (T1) is already being busy with block.

No solution was there - T2 will go to suspended state and when T1 will finish their execution it will notify then only t2 can know that resource is free now.

When one thread is executing in one method and call two more method like.

Synchronized {
obj.method1 ();
}
Method1 () {
Call method2 ();
}
Method2 () {
Sys (“Done!”);
}
If thread1 want to release the lock in method 2 it was not possible, t1 will come back to synchronized block and release lock by coming out the synchronized block.


Two Important Feature Not Available with Synchronized

1-Synchronized blocks don’t offer any mechanism to query the status of “waiting queue” of threads for a particular resource.

2-The synchronized block have to be present within the same method. A synchronized block cannot start in one method and end in another.

The synchronized block must be fully contained within a single method. A Lock can have it’s calls to lock() and unlock() in separate methods.

Difference between Lock Interface and synchronized keyword

The main differences between a Lock and a synchronized block are:
1) Having a timeout trying to get access to a synchronized block is not possible. Using Lock.tryLock(long timeout, TimeUnit timeUnit), it is possible.
Java concurrency lib implementations provide additional functionality over the use of synchronized, they providing a non-blocking attempt to acquire a lock (tryLock()), an attempt to acquire the lock that can be interrupted (lockInterruptibly(), and an attempt to acquire the lock that can timeout (tryLock(long, TimeUnit)).
A Lock class is quite different from that of the implicit monitor lock, it can provide guaranteed ordering, reentrant usage and deadlock detection.
An example of some ReentrantLocks using tryLock() :

What is Non-Blocking Attempt to acquire the lock?

Generally when we want to get a lock in Java, there was a method using synchronized? We call it on object like synchronized (object).Currently if lock is not available (some another thread already acquired) then your thread will go to block state. It is call Blocking Attempt to acquired lock.
When we invoked synchronized (object), and if your thread does not get lock and also not going to block state,means that it will not wait to release the lock, this is called Non-Blocking way of lock acquired. While this functionality is provided with synchronized keyword, after some year with jdk1.5 they introduced a new feature we called it Reentrant lock class. Its provide those functionality which you are demanding above.
Its provide this behavior in 3 flavor (3 method).

1)-tryLock()-if lock is available ,it provide the calling thread if no lock available then  thread would not be locked (this feature not available with synchronized keyword).

2)-lockInterruptibly ()- If lock is available its provide to calling thread, if not then it will be blocked .Blocked but it can be interrupted ,to come out from block state.

3)-tryLock(long ms,TIMEUNIT)- it lock is available its provided to calling thread ,if not then it will go to Block state for MS (milliseconds) which provide in parameter. After MS time, it will come out from block state.
Example-        
Runnable r = new Runnable() {
 @Override
 public void run() {
boolean lockAcquired = false;
try {
lockAcquired = lock.tryLock(1000*3,TimeUnit.MILLISECONDS);
System.out.println(lockAcquired + " lock acquired by " + Thread.currentThread().getName());
if (lockAcquired) {
Thread.sleep(1000 * 10);
} else {
                        System.out.println("I hav'not found the lock " + Thread.currentThread().getName());
 }
 } catch (InterruptedException e) {
                                                            // TODO Auto-generated catch block
  e.printStackTrace();
} finally {
                                                            if (lockAcquired) {
                                                                        lock.unlock();
                                                                        System.out.println("Unlocked By " + Thread.currentThread().getName());
                                                            }
                                                }

                                    }
                        };
                        Thread t1 = new Thread(r, "Thread1");
                        Thread t2 = new Thread(r, "Thread2");


No comments:

Post a Comment