Monday, October 21, 2013

Locks in Java : Concurrency

Explicit locking mechanism can be used to coordinate access to shared resources in a multi-threaded environment without using the keyword synchronized. The Lock interface, which is declared in the java.util.concurrent.locks package, defines the explicit locking operations. The ReentrantLock class, in the same package, is the concrete implementation of the Lock interface.
In this post, we look into java.util.concurrent.locks package and see how it is useful and why such package is introduced. This is one of the low level API other than java.util.concurrent.atomic.

Locks
Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements. They allow more flexible structuring, may have quite different properties, and may support multiple associated Condition objects.

The Lock interface is declared as follows:

The use of the lock() method to acquire a lock behaves the same as the use of the synchronized keyword. The use of the synchronized keyword requires that a thread should acquire and release an object’s monitor lock in the same block of code. When you use the synchronized keyword to acquire an object’s monitor lock, the lock is released by the JVM when the program leaves the block in which the lock was acquired. This feature makes working with intrinsic locks very simple and less error prone. However, in the case of the Lock interface, the restriction of acquiring and releasing of the lock in the same block of code does not apply. This makes it a little flexible to use; however, it is more error prone because the responsibility of acquiring as well as releasing the lock is on the programmer.

You must make sure that you release the lock by calling the unlock() method of the Lock interface after you are done with the lock.The use of a try-finally block is necessary in this case because no matter how you finish returning from this method after you call myLock.lock(), you would like to release the lock. This can be assured only if you place the call to the unlock() method inside the finally block.

You may wonder why you would use the code structure when you could have used the synchronized keyword to achieve the same effect, like so:
You are correct in thinking that using the synchronized keyword would have been better in this case. It is much simpler and less error prone to use the synchronized keyword in such situations. The power of using the new Lock interface becomes evident when you come across situations where using the synchronized keyword is not possible or very cumbersome.
For example, if you want to acquire the lock in the updateResource() method and release it in some other methods, you cannot use the synchronized keyword. If you need to acquire two locks to work with a shared resource and if only one lock is available, you want to do something else rather than waiting for the other lock. If you use the synchronized keyword or the lock() method of the Lock interface to acquire a lock, the call blocks if the lock is not available immediately, which gives you no option to back off once you asked for the lock. Such blocked threads cannot be interrupted either.

The two methods of the Lock interface, tryLock() and lockInterruptibly(), give you the ability to try to acquire a lock (rather than acquire a lock or block). The thread that has acquired the lock can be interrupted if it is blocked. The syntax to acquire and release a lock using the Lock interface should use a try-finally or a try-catch-finally block structure to avoid unintended bugs by placing the unlock() call in a finally block.

Everybody know the main advantage of using the synchronized keyword (implicit locking) is that you don’t have to remember to release the lock in a finally block since, at the end of the synchronized block (or method), code will be generated to automatically release the lock.
Although this is a useful feature, there are some situations where you may need to control the release of the lock manually.
Lock objects provide this flexibility. However, it is your responsibility to ensure that you release the lock in a finally block while using Lock objects

Snippet describes the usage idiom for a Lock:

Lock lock = /* get Lock type instance */;
 lock.lock();

 try {
  // critical section
 }
 finally {
  lock.unlock();
 }

Another difference between implicit locks and explicit Lock objects is that you can do a “non-blocking attempt” to acquire locks with Locks.
Non-blocking attempt means You get a lock if that lock is available for locking, or you can back out from requesting the lock using the tryLock() method on a Lock object. If you acquire the lock successfully, then you can carry out the task to be carried out in a critical section; otherwise you execute an alternative action.

It is noteworthy that an overloaded version of the tryLock() method takes the timeout value as an argument so that you can wait to acquire the lock for the specified time.
tryLock(long time, TimeUnit unit)

Snippet describes the usage idiom for a Lock with tryLock():

Lock lock = /* get Lock type instance */;
 if(tryLock()) {
  try {
   // critical section
  }
  finally {
   lock.unlock();
  }
 }
 else {

 }

Using tryLock() helps avoid some of the thread synchronization-related problems such as deadlocks and livelocks. Click to see what is deadlock 

Example
We will solve a classic synchronization problem known as the dining-philosophers problem using the explicit lock constructs. The problem goes like this: five philosophers spend all of their time either thinking or eating. They sit around a circular table with five chairs and five forks. There are only five forks and all five philosophers need to pick the two nearest (one from his left and one from his right) forks to eat.
Once a philosopher finishes eating, he puts down both forks and starts thinking. A philosopher cannot pick up a fork if his neighbor is using it. What happens if each of the five philosophers picks up one fork from his right and waits for his left fork to be released by his neighbor? This would be a deadlock situation and no philosopher would be able to eat. This deadlock condition can be avoided easily by using the tryLock() method of the Lock interface. This method returns immediately and it never blocks. If the lock is available, it gets the lock and returns true. If the lock is not available, it returns false.

To create a philosopher, you would use code like:
Lock fork1 = new ReentrantLock();
..
Lock fork5 = new ReentrantLock();

Philosopher p1 = new Philosopher(fork1, fork2, "A");
...
Philosopher p5 = new Philosopher(fork5, fork1, "E");

You run all five philosophers in five different threads to simulate the dining-philosophers problem. Read the code in the eat() method carefully. It tries to get the left and right forks one at a time. If you can get only one fork and not the other, you put down the one you got so others can have it. The code in the eat() method has only the logic to get the forks. In a real program, if you cannot get both forks, you would like to wait for some time and try again to pick up the forks. You will have to write that logic.


A reentrant mutual exclusion Lock with the same basic behavior and semantics as the implicit monitor lock accessed using synchronized methods and statements, but with extended capabilities



Related Post
How thread exchange data in java

Best way to synchronize primitive datatypes in java
Basic introduction to thread in detail
Collection Framework overview with 2 pictures



If you know anyone who has started learning java, why not help them out! Just share this post with them.  Thanks for studying today!...

Sunday, October 20, 2013

Atomic Variables in Java : Concurrency

When you implement a concurrent application that has one or more objects shared by several threads, you have to protect the access to their attributes using a synchronization mechanism as locks or the synchronized keyword to avoid data inconsistency errors
These mechanisms have the following problems:

  • Deadlock: This situation occurs when a thread is blocked waiting for a lock that is  locked by other threads and will never free it. This situation blocks the program, so it will never finish.
  • If only one thread is accessing the shared object, it has to execute the code necessary to get and release the lock.

However, there is also an efficient alternative ways to primitive data types that avoid using synchronized keyword. In this post, we'll see how we can synchronize primitive data types in a efficient way.




To provide a better performance to this situation, the compare-and-swap operation was developed. This operation implements the modification of the value of a variable in the following three steps:

  • You get the value of the variable, which is the old value of the variable.
  • You change the value of the variable in a temporal variable, which is the new value of the variable.
  • You substitute the old value with the new value, if the old value is equal to the actual value of the variable. The old value may be different from the actual value if another thread has changed the value of the variable.
With this mechanism, you don't need to use any synchronization mechanism, so you avoid deadlocks and you obtain a better performance.

Java implements this mechanism in the atomic variables. These variables provide the compareAndSet() method that is an implementation of the compare-and-swap operation and other methods based on it. Java also introduced atomic arrays that provide atomic operations for arrays of integer or long numbers. In this post, you will learn how to use the AtomicIntegerArray class to work with atomic arrays.



The java.util.concurrent package has two sub-packages:
  1. java.util.concurrent.atomic 
  2. java.util.concurrent.locks
These are low level API's where as semaphore, CountDownLatch, Exchanger, CyclicBarrier are high-level concurrency abstractions. However, they provide more fine-grained control when you want to write multithreaded code.

Atomic Variables
Atomic variables were introduced in Java Version 5 to provide atomic operations on single variables. When you work with a normal variable, each operation that you implement in Java is transformed in several instructions that is understandable by the machine when you compile the program. For example, when you assign a value to a variable, you only use one instruction in Java, but when you compile this program, this instruction is transformed in various instructions in the JVM language. This fact can provide data inconsistency errors when you work with multiple threads that share a variable.

To avoid these problems, Java introduced the atomic variables. When a thread is doing an operation with an atomic variable, if other threads want to do an operation with the same variable, the implementation of the class includes a mechanism to check that the operation is done in one step. Basically, the operation gets the value of the variable, changes the value in a local variable, and then tries to change the old value for the new one. If the old value is still the same, it does the change. If not, the method begins the operation again. This operation is called Compare and Set.

Atomic variables don't use locks or other synchronization mechanisms to protect the access to their values. All their operations are based on the Compare and Set operation. It's guaranteed that several threads can work with an atomic variable at a time without generating data inconsistency errors and its performance is better than using a normal variable protected by a synchronization mechanism.

Here is a list of some of the classes in this package and their short description:


Only AtomicInteger and AtomicLong extend from Number class but not AtomicBoolean. All other classes in the java.util.concurrent.atomic subpackage inherit directly from the Object class. Here we'll discuss AtomicInteger and the same thing apply to rest the of the classes.

In Java the integer primitive increment operation is not an atomic operation. When an integer is ncremented, the following logical steps are performed by the JVM

  1. Retrieve the value of the integer from memory
  2. Increment the value
  3. Assign the newly incremented value back to the appropriate memory location
  4. Return the value to the caller
So while we write the increment operator in a single line of Java code, such as:
int n = j++;
Each one of the aforementioned steps occurs in the JVM. The danger is that if you have multiple threads that all try to increment the same value, there is a chance that two or more of the threads will get the same value.

Each of these atomic classes provides methods to perform common operations, but each one is ensured to be performed as a single atomic operation. For example, rather than incrementing an integer using the standard increment operator.

You can ensure that the 
  1. get value
  2. increment value
  3. update memory, and
  4. assign the new value to n 

is all accomplished without fear of another thread interrupting your operation by writing you code as follows.

AtomicInteger ai = new AtomicInteger(0);
int n = ai.incrementAndGet();



AtomicInteger
Important Methods in the AtomicInteger Class which are self explanatory and you don't have remember it's description. Have a look !


Let's try out an example to understand AtomicInteger or AtomicLong.
Suppose you have  a counter value that is public and accessible by all threadsHow do you update or access this common counter value safely without introducing the data race problem?
Simplest way is to synchronized keyword to ensure that the critical section is accessed by only one thread at a given point in time. The critical section will be very small, as in

However, this code is inefficient since it acquires and releases the lock every time just to increment the value of count. Alternatively, if you declare count as AtomicInteger or AtomicLong (whichever is suitable), then there is no need to use a lock with synchronized keyword

In this example, I demonstrate how incrementing normal integer and incrementing "atomic" interger are different and which is thread safe.Incrementing a shared Integer object without in a data race; however, incrementing a shared AtomicInteger will not result in a data race.



Sample Output
Increment value of atomicInteger : 1
Increment value of integer : 1
Increment value of integer : 1
Increment value of integer : 1
Increment value of atomicInteger : 2
Increment value of atomicInteger : 3

Have you noticed in the above output that Integer object is resulted in Race Condition, the final value of integer after incrementing 3 times is 1. For atomicInteger, however, it is 3.


Related Post
Class Loader concept in detail
How Thread exchange data in Java

If you know anyone who has started learning Java, why not help them out! Just share this post with them. Thanks for studying today!...

Wednesday, October 16, 2013

LinkedBlockingDeque in java

LinkedBlockingDeque implements the BlockingQueue interface. Before moving further, please a look at the BlockingQueue interface that help you better understand LinkedBlockingDeque  and it's methods.



LinkedBlockingDeque 
Blocking means Attempts to put an element into a full LinkedBlockingDeque will result in the operation blocking;attempts to take an element from an empty LinkedBlockingDeque will similarly block. 
Deque means you can insert and remove the element from both the ends.
Linked means element are linked to each other and know who is in front and at the back.

  • Optionally-bounded blocking deque based on linked nodes.
  • Linked nodes are dynamically created upon each insertion unless this would bring the deque above capacity.
  • This class does not permit null elements.
  • Concurrent scalable optionally bounded FIFO blocking deque backed by linked nodes.

How to create LinkedBlockingDeque?
  • LinkedBlockingDeque() : Creates a LinkedBlockingDeque with a capacity of Integer.MAX_VALUE.
  • LinkedBlockingDeque(int capacity) : Creates a LinkedBlockingDeque with the given (fixed) capacity.
  • LinkedBlockingDeque(Collection<? extends E> c) : Creates a LinkedBlockingDeque with a capacity of Integer.MAX_VALUE, initially containing the elements of the given collection, added in traversal order of the collection's iterator.

There are few basic methods like add( E e ), elemet(), offer( E e ), peek() etc which are already discussed in Blocking interface. Here we discuss methods which is particularly  useful in case of LinkedBlockingDeque 


Modifier and Type Method  Description
void addFirst(E e) Inserts the specified element at the front of this deque if it is possible to do so immediately without violating capacity restrictions, throwing an IllegalStateException if no space is currently available.
void addLast(E e) Inserts the specified element at the end of this deque if it is possible to do so immediately without violating capacity restrictions, throwing an IllegalStateException if no space is currently available
E getFirst() Retrieves, but does not remove, the first element of this deque.
E getLast() Retrieves, but does not remove, the last element of this deque.
boolean offerFirst(E e) Inserts the specified element at the front of this deque if it is possible to do so immediately without violating capacity restrictions, returning true upon success and false if no space is currently available.
boolean offerLast(E e) Inserts the specified element at the end of this deque if it is possible to do so immediately without violating capacity restrictions, returning true upon success and false if no space is currently available.
E peekFirst() Retrieves, but does not remove, the first element of this deque, or returns null if this deque is empty.
E peekLast() Retrieves, but does not remove, the last element of this deque, or returns null if this deque is empty.
E pollFirst() Retrieves and removes the first element of this deque, or returns null if this deque is empty.
E pollLast() Retrieves and removes the last element of this deque, or returns null if this deque is empty.



Let see an example of usage of above methods.

Sample Output
[10, 43, 32]

Adding element at the front 45
[45, 10, 43, 32]

Adding elemet at the end 67
[45, 10, 43, 32, 67]

head of the deque/ the first element of this deque 
45
First element of deque
45
Last elementof deque
67

[45, 10, 43, 32, 67]
First element and remove it
45
[10, 43, 32, 67]

Last element and remove it
67
[10, 43, 32]

[10, 43, 32, 413, 31, 91, 13]

Size of deque : 7


Methods which are useful in case where multiple thread are use because they wait until some condition is met


Modifier and Type Method  Description
void put(E e) Inserts the specified element into the queue represented by this deque (in other words, at the tail of this deque), waiting if necessary for space to become available.
void putFirst(E e) Inserts the specified element at the front of this deque, waiting if necessary for space to become available.
void putLast(E e) Inserts the specified element at the end of this deque, waiting if necessary for space to become available.
E take() Retrieves and removes the head of the queue represented by this deque (in other words, the first element of this deque), waiting if necessary until an element becomes available.
E takeFirst() Retrieves and removes the first element of this deque, waiting if necessary until an element becomes available.
E takeLast() Retrieves and removes the last element of this deque, waiting if necessary until an element becomes available.


Producer Consumer problem with LinkedBlockingDeque 

Sample output
[0]:  consumed(0)  :[]
[]: inserted(0) :[]
[1]: inserted(1) :[1]
[1, 2]: inserted(2) :[1, 2]
[1, 2, 3]: inserted(3) :[1, 2, 3]
[1, 2, 3, 4]: inserted(4) :[1, 2, 3, 4]
[1, 2, 3, 4, 5]: inserted(5) :[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]:  consumed(1)  :[2, 3, 4, 5, 6]
[2, 3, 4, 5, 6]: inserted(6) :[2, 3, 4, 5, 6]
[2, 3, 4, 5, 6]:  consumed(2)  :[3, 4, 5, 6]
[3, 4, 5, 6, 7]: inserted(7) :[3, 4, 5, 6, 7]
[3, 4, 5, 6, 7]:  consumed(3)  :[4, 5, 6, 7]
[4, 5, 6, 7, 8]: inserted(8) :[4, 5, 6, 7, 8]
[4, 5, 6, 7, 8]:  consumed(4)  :[5, 6, 7, 8]
[5, 6, 7, 8, 9]: inserted(9) :[5, 6, 7, 8, 9]
[6, 7, 8, 9, 10]: inserted(10) :[6, 7, 8, 9, 10]

[5, 6, 7, 8, 9]:  consumed(5)  :[6, 7, 8, 9, 10]

Have you notice from the above output that element are consumed from the head of the deque and put() wait until consumer thread consume the element from deque.

Changed the method takeFirst() to takeLast(), try the above code. Sample output after changing the method name.

Sample Output
[0]: inserted(0) :[]
[0]:  consumed(0)  :[]
[1]: inserted(1) :[1]
[1, 2]: inserted(2) :[1, 2]
[1, 2, 3]: inserted(3) :[1, 2, 3]
[1, 2, 3, 4]: inserted(4) :[1, 2, 3, 4]
[1, 2, 3, 4, 5]: inserted(5) :[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]:  consumed(5)  :[1, 2, 3, 4]
[1, 2, 3, 4, 6]: inserted(6) :[1, 2, 3, 4, 6]
[1, 2, 3, 4, 7]: inserted(7) :[1, 2, 3, 4, 7]
[1, 2, 3, 4, 6]:  consumed(6)  :[1, 2, 3, 4, 7]
[1, 2, 3, 4, 7]:  consumed(7)  :[1, 2, 3, 4]
[1, 2, 3, 4, 8]: inserted(8) :[1, 2, 3, 4, 8]
[1, 2, 3, 4, 8]:  consumed(8)  :[1, 2, 3, 4]
[1, 2, 3, 4, 9]: inserted(9) :[1, 2, 3, 4, 9]
[1, 2, 3, 4, 10]: inserted(10) :[1, 2, 3, 4, 10]

[1, 2, 3, 4, 9]:  consumed(9)  :[1, 2, 3, 4, 10]


Related Post
PriorityQueue in java with examples
PriorityBlockingQueue in Java with examples
ArrayBlockingQueue in Java with Examples


If you know anyone who has started learning Java, why not help them out! Just share this post with them. 
Thanks for studying today!...

Monday, October 14, 2013

ArrayBlockingQueue Examples in Java

ArrayBlockingQueue implements the BlockingQueue interface. Before moving further, please a look at the BlockingQueue interface that help you better understand ArrayBlockingQueue and it's methods.




ArrayBlockingQueue
  • A bounded blocking queue backed by an array. It store the element internally in an array.That why is it called ArrayBlockingQueue.
  • This queue orders elements FIFO (first-in-first-out).
  • The head of the queue is that element that has been on the queue the longest time.
  • The tail of the queue is that element that has been on the queue the shortest time.
  • New elements are inserted at the tail of the queue, and the queue retrieval operations obtain elements at the head of the queue.

This is a classic "bounded buffer", in which a fixed-sized array holds elements inserted by producers and extracted by consumers. Once created, the capacity cannot be changed. Attempts to put an element into a full queue will result in the operation blocking;attempts to take an element from an empty queue will similarly block. We'll see an example of this also.

Let's have a look at the basic methods and it's working with the help of example
Modifier and Type Method  Description
boolean add(E e) Inserts the specified element at the tail of this queue if it is possible to do so immediately without exceeding the queue's capacity, returning true upon success and throwing an IllegalStateException if this queue is full.
boolean offer(E e) Inserts the specified element at the tail of this queue if it is possible to do so immediately without exceeding the queue's capacity, returning true upon success and false if this queue is full.
E peek() Retrieves, but does not remove, the head of this queue, or returns null if this queue is empty.
E poll() Retrieves and removes the head of this queue, or returns null if this queue is empty.
void put(E e) Inserts the specified element at the tail of this queue, waiting for space to become available if the queue is full.
E take() Retrieves and removes the head of this queue, waiting if necessary until an element becomes available


This example demonstrate the difference between add() and offer() method. 
Sample Output
[3]
[3, 5]
[3, 5, 7]
[3, 5, 7, 4]
[3, 5, 7, 4, 9]
you can see element are added to tail
size of queue : 5
size of queue : 5

Now try the same code by un-commenting the line blockQue.add(9);

Sample output
[3]
[3, 5]
[3, 5, 7]
[3, 5, 7, 4]
[3, 5, 7, 4, 9]
you can see element are added to tail

size of queue : 5
Exception in thread "main" java.lang.IllegalStateException: Queue full
at java.util.AbstractQueue.add(Unknown Source)
at java.util.concurrent.ArrayBlockingQueue.add(Unknown Source)
at ArrayBlockingQueueDemo.main(ArrayBlockingQueueDemo.java:21)

You can see, add() method is throwing IllegalStateException because it's trying to increase the capacity of the queue. 

This example demonstrate how FIFO order is follow while adding and removing element from queue.

Sample Output
[3]
[3, 5]
[3, 5, 7]
[3, 5, 7, 4]
[3, 5, 7, 4, 9]
you can see new elements are added to tail
Head of the queue & remvoing: 3
[5, 7, 4, 9]
Head of the queue & remvoing: 5
[7, 4, 9]
new element (32) added at the tail true
[7, 4, 9, 32]


Producer-Consume problem with ArrayBlockingQueue 
In this example, we create ArrayBlockingQueue of size 3 in which producer insert element in a while loop and consumer thread consume element in a while loop. In while loop, if we insert more than 3 element it blocks until consumer consume element from the same queue.
Sample Output
0 inserted in queue
Consume element : 0
1 inserted in queue
2 inserted in queue
3 inserted in queue
Consume element : 1
4 inserted in queue
Consume element : 2
5 inserted in queue
Consume element : 3
6 inserted in queue

You'll notice from the above output that queue was bounded to 3 element at a time that how it's differ from unbounded queue where producer produce element without waiting.
You can try the above code  by changing queue size to 1. where only element will be in a queue until consume by consumer.



Related Post
PriorityQueue in java with examples
PriorityBlockingQueue in java with examples
How thread exchange data with exchange() method
How thread works in phases 

If you know anyone who has started learning Java, why not help them out! Just share this post with them. 
Thanks for studying today!...