Monday, 22 March 2010

Java.util.Concurrent, Part 3 - Queues

In multi-threaded programming, its common to have both producers that create or
retrieve from something external, and also consumers that process what ever retrieved. Since there no knowing in general how quickly either process happen. In between we need a Queue of objects waiting to be processed. Java.util.Concurrent adds blocking queue. Queues are extensions to the collections API which means you can use the generics mechanism to state what type of object you put into them. Here are the basic methods common to any blocking queue. Where a non block queue was has methods that throw exception if the queue is too empty or too full, a block queue has methods that wait until the situation is resolved. Blocking queue operation may be considered atomic from the point of view of threads.

voidput(O)Adds a element to the queue, or waits for space.
booleanoffer(O)Adds a element to the queue, if there is space or returns false.
booleanoffer(O, long timeout, TimeUnit unit)Adds a element to the queue, or wait so long for space then returns false.
Objecttake()Take an element from the head of the queue, or waits for one to be there
booleanpoll(long timeout, TimeUnit unit)Adds a element to the queue, or waits the given time for space.

You can also measure fullness of the queue with remainCapacity() or copy all the element to another collection with drainTo().

Standard Queue backed by LinkedLists or Arrays are both available as our.

Backed by a linked list

ArrayBlockingQueueBacked by any Array
DelayQueueeach element .getDelay(), the take method take the element whose .getDelay() method has fallen further below zero, or wait until then
PriorityBlockingQueueThe priority, the first element to be returned is order by a Comparator (or Natural ordering, alphabetical for String etc)
SychronousQueueStores nothing, waits until both a take and a put thread are blocking at the same time.

Saturday, 20 March 2010

Java.util.Concurrent, Part 2 - Conditions

In the Java 5 and newer API, Conditions are Object designed to replace the simple wait and notify tasks in the earlier API. You get a Condition object, by calling the NewCondition method on any lock, you can make as many Conditions as you like on one lock. You can make a thread wait on the Condition one of 5 ways.

void await()Until a Signal or Interrupted
booleanawait(long, TimeUnit unit)For a set time, or a Signal or Interrupted, returns true if woken by Signal or Interrupt
longawaitNanos()Wait a time in Nanoseconds, return how much waiting time was left, if signalled
voidawaitUniterruptable()Only a Signal will awake this method
booleanawaitUntil(Date deadline)Waits until deadline or signalled, return true if signalled

All these methods, release the lock the condition was make from, where waiting. One
of to method might be used to singal the waiting condition.

voidsignal()Signal to wake one waiting condition
voidsignalAll()Signal to wake all waiting conditions

In a queue example, we would want to wake up only one waiting thread. But if a major tasked finished, we might wan't to wake up a the waiting threads.

Java.util.Concurrent, Part 1 - Locks

You might have missed this glem in API, Released back in 2006 with Java 5.0, util.Concurrent is a Java API extention, giving all sorts of tricks and methodology for hightly multithreaded code. With chips becoming ever more multithreaded, perphaps
even 512 way by 2020. Your find yourself ever push to make more use of multiple threads. And the Concurrent API certainly make it easier. Lets have a look at some of the tricks in the new API.

Locks, in old fashioned java, when you had a critical set of code, a piece you want to be sure, only one thread was going to run at a time. You use to have to synchronize it on a object invented for the task. But in Java 5 and onwards have also proper locks in a variatly of types.

import java.util.concurrent.lock;

Lock myLock = new ReentractLock();

try {
   // Thread safe code
finally {

The API provide to general interfaces, Lock and ReadWriteLock, and three classes, RentrantLock, RentrantReadWriteLock.ReadLock, RentrantReadWriteLock.WriteLock. Rentrant means the calling class can try and gain the lock as many times as it like without problems, only once it was unlock as many lock as it has acquired will another thread beable to acquire the lock. The RentractReadWriteLock is usually for double end object such as queues, seperate class may be able to gain different locks. Allowing different threads to be reading and writing the queue at the same time.