0% found this document useful (0 votes)
106 views60 pages

Concurrency in Java - A Beginner's: What Are Threads

The document discusses concurrency and threads in Java. It defines threads as distinct flows of control within a program that share the same memory space. This allows for data sharing between threads but can cause race conditions if not properly synchronized. The document then discusses how to make classes thread-safe by allowing free reading of shared data but synchronizing writing through locks. It provides an example class that demonstrates adding and removing employees from a thread-safe list in a synchronized manner.

Uploaded by

naresh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
106 views60 pages

Concurrency in Java - A Beginner's: What Are Threads

The document discusses concurrency and threads in Java. It defines threads as distinct flows of control within a program that share the same memory space. This allows for data sharing between threads but can cause race conditions if not properly synchronized. The document then discusses how to make classes thread-safe by allowing free reading of shared data but synchronizing writing through locks. It provides an example class that demonstrates adding and removing employees from a thread-safe list in a synchronized manner.

Uploaded by

naresh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 60

Concurrency in Java A Beginners

introduction
Concurrency and parallelism features in Java are as old as Java itself. The original creators and
specification authors rightly presumed that programmers and future state software designs would
need high concurrency capabilities to scale their apps. The Java platform is designed from the
ground up to support concurrent programming, with basic concurrency support in the Java
programming language and the Java class libraries. Since version 5.0, the Java platform has also
included high-level concurrency APIs to ease the complex semantics of working with and
understanding Threading behaviors.

What are Threads


Conceptually, a thread is a distinct flow of control within a program. A thread is similar to the
more familiar notion of a process, except that multiple threads within the same application share
much of the same statein particular, they run in the same address space or memory space.

Sharing the address space between threads has a big advantage as it allows reuse of the same
data space between threads. If we have a separate small data stack, local to each thread, then data
sharing and data synchronization can become a big problem in programs. This is essentially the
same situations which we encounter related to Session state sharing across JVM clusters in a
production clustered environments. Distinct address spaces would require a complex mechanism
to share the mutable state across thread spaces as soon as the thread mutates its local address
space. In essence it would require address space synchronization mechanisms built into the
processor platforms that use Java.

So to prevent this problem threads dont hold their own state (except when you use
ThreadLocal) but instead rely on the programs address space for all their data input needs.
Though this solves the immediate problems of data synchronization across threads but this
creates another set of issues called race conditions which can make threads see stale data view of
a master address space. However this problem is much easier to solve by building thread safe
classes.

What is Thread Safety


Thread safety is an invariable attempt to design class constructs so that their objects or instances,
when accessible from multiple threads, still demonstrate the idempotent behavior as they would
if accessed from a single threaded model.

Since a single thread model access to an object is not a valid multithreaded model para-diagram,
hence no matter how well an object or a component set behaves in a single thread model setup, it
cannot be succinctly called thread-safe. Whether an object needs to be thread safe or not
depends on how that object is used instead of what it does. For some situations complete thread
safety may be a high requirement, but in some other cases a 95% to 98% thread safety coverage
may be sufficient.

Thread safety problem are always caused when two or more threads have mutable access to same
shared data set. When threads start reading and writing some shared variable without any control
then data based problems happen. Since threads share the same address space this is bound to
happen, especially when we have to rely on the Operating Systems capabilities and good faith
about when to swap the threads in and out. Application design should strive to build classes and
components to be thread safe from the very beginning. Age old concepts of encapsulation and
abstraction are our best friends here. Debugging and refactoring a poorly written component set
to be thread safe can be a herculean task and sometimes even a nightmare. So its important to
understand and employ correct thread safe class deign principles form the very start.

How to make classes Thread Safe.


At a high level, thread safety is a very simple concept, theoretically. If we allow free reading
access to an objects state but control the writing access we can make the object 100% thread
safe. This is the most common sense way to do it. We need to take care of two things here:

As long as the variable of state is not being modified e.g: a final int value, it is safe to
allow multiple threads to read it freely.
When an action involves a write operation to be executed, we get and hold a lock on the
variable and dont allow any read operations to pursue until the write is finished. This is
essentially what volatile does.

To make this strategy a flying success only thing that we need to do, as programmers, is make
sure that when write blocks the read operations, the read and write operations use the same lock
mechanism to test if the lock is free or not. If we can do this then we can get perfect thread
safety. This is exactly what the synchronized keyword or intrinsic locks (or monitor locks) do.
Though our programs would start behaving correctly in a multithreaded setup, however, this
approach has two big problems both of which convene to the same outcome.

Threads would block each other: When a write operation happens the read would block
since we have synchronized the write blocks. Then again when a read happens, the write
and other reads would also have to be blocked because in a multithreaded setup we really
dont know exactly when a read or a write would happen and thus we need to
synchronize the reads also to prevent them from being interleaving with writes. So in the
end we essentially are making the program single threaded in nature. Since only one
thread would always actually be alive doing the read/write, so even if we have hundreds
of threads they just wait out for a chance. Business money wise, we are not making an
effective use of those 8 CPUs with 4 cores each (that we have in production environment)
since at any time only 1 thread would be active when we could harness about 32 threads
in parallel. This is exactly the problem in any synchronized java class and in the
ConcurrentCollections of the java.util API.
Performance problems: With a multithreaded program in place its easy to expect it to
perform faster since we have made it multithreaded now. But because of the problem
explained in above point, code depicts no better behavior then it would in a single
threaded model. So blocking threads again convene our program to a single thread model
behavior.

To solve these problems we can make a few changes in our programming practice.Though we
would still synchronize on read and write operations, but his time we would intelligently keep
the blocking scope to the minimal in our code. This is to say that we dont synchronize the whole
method, just eh part of code in the method which actually mutates the shared data.

The following example code shown a typical use of synchronized thread safe idiom.

@ThreadSafe
1 public class EmployeeManager2 {
2 /*
3 * Mutating operations are encapsulated inside the class.
4 * State (employees) is not shared outside class directly.
*/
5 private List<Employee> employees;
6
7 public void addEmployee(Employee e){
8 //do some validations or preprocessing
9 synchronized(this){
//only this code blocks
10
this.employees.add(e);
11 }
12 //do somehting else
13 }
14
15 /*
* This is the right way to get data from collections.
16 * Finding by index is not safe as index may change over time.
17 */
18 public Employee getEmployee(String name)
19 throws CloneNotSupportedException{
20 //get the employee from the list
Employee employee = this.findEmployeeByName(name);
21 if(employee != null){
22 return (Employee)(employee.clone());
23 }else{
24 return null;
}
25 }
26
27 public void deleteEmployee(String name){
28 //get the employee from the list
29 synchronized(this){
30 for (Iterator<Employee> it = employees.iterator();
it.hasNext();) {
31 Employee employee = it.next();
32 if(employee.getName().equals(name)){
33 it.remove();//delet the employee
34 break;
}
35
}
36 }
37 }
38
private Employee findEmployeeByName(String name){
39 for (Iterator<Employee> it = employees.iterator();
40it.hasNext();) {
41 Employee employee = it.next();
42 if(employee.getName().equals(name)){
return employee;
43 }
44 }
45 return null;
46 }
47}
48
49
50
51
52
53
54
55

Object Behavior Heuristics


EmployeeManager2 gave a simple example about how to make use of thread safe constructs
without compromising on concurrency. However as the programs evolve in size, the problem of
thread safe also increases exponentially. e.g. assume that we have to calculate an employees
total CTC package and tax structures also and should be available for reading once the employee
is loaded in the list.

One way to do it is to have the individual components of the CTC package and tax formulas
within the employee object itself and when the employee is added to the list we do the
calculation in the synchronized block and populate the variables with the employee accordingly.
However this approach though still preserves the thread safety of the EmployeeManager but
creates a problem for us by expanding the scope of the synchronized block and thus the blocking
part of the add action and thus the performance of the manager.

Another approach would be to save the CTC and tax structure objects separately in another List
in the manager and ensure that the CTC and tax objects are navigable by the employee name/id.
This approach gives us a good performance heads up but then would again require us to
synchronize on the other two lists. This approach also gives us an added advantage of allowing
us to keep the employee add operation separate and mutually exclusive of the CTC package
add and tax structure add operations, thus allowing us a provision to induce parallelism
between the three.

A more preferred approach to do this, and essentially a variation of the second approach given
above, would be to keep the CTC and tax information within the employee itself, but to just
make their calculation actions parallel and mutually exclusive. Since we can retrieve the CTC
and tax operations are tied to an employee by his or her name/id so provided an employee id we
can calculate and mutate its CTC and tax structures in parallel while the manager serves its
clients. This approach is not only thread safe but also performance efficient.

However there is one small problem induced by our changing requirements (because our clients
think they are privileged few and can do anything they want). The client now says that unless the
tax structure is calculated and available for introspection, CTC should not be available for
viewing even if it has been calculated and vice versa. This essentially means that unless both the
operations of CTC calculation and tax structure calculation have finished successfully we cannot
disclose the CTC and tax information to the outside world i.e. outside the EmployeeManager.

What our client requirement mandates us to do is convert a singular parallel operation into an
atomic operation.

Atomicity
Atomic operations are a real world requirement and essentially a thread safety hazard because of
inherent thread nature to incline towards race conditions. Simplest of these problems, in an
increment or a decrement operation. E.g. a counter to keep track of number of requests served
per day in the web service or a counter to track the number of login failure attempts for a user. A
simple i++ operation is essentially composed of a set of 3 operations working together. Though
we dont see that in Java source but a disassemble operation can easily point out this
misconception. Allowing us the easy convention of ++ operator does not mean that java
internally also treats this as a single operation.

Consider the following harmlessly looking code:

1
public class Temp {
2
3 public static void main(String[] args) {
4 int i=0;
5 i++;
6 System.out.println(i);
}
7}
8

And this is what the above code actually translates into. We can verify that using the javap
command tool with the disassemble flag.
Lets walk through this part to see how we would be harmed by the harmless code.

A. Assembly operation 0. Does the initialization of a variable and pushes the initial value of 10
into the variable. The bipush JVM instruction set takes a single 32 bit length (int) value and
pushes it on the operand stack.

B. Assembly operation 2. Pops the latest value in the operand stack and stores the value in a local
variable. The variable name is 1 and not i. Note that variable name in Java source code are just
human readable denominations and not actually the ones used by assembly JVM machine set. In
our example this instruction pops the value of 10 and stores in a memory address offset labeled
as 1 for it to read from later.

C. Assembly operation 3. Increments the variable. The iinc operator JVM machine set operator
takes 2 parameters.

First parameter is the name of the assembly level variable whose value is to be
incremented. In our case this variable name is 1, derived from B. above.
Second parameter is the value by which to increment which in our case is 1.

This operation saves the new value back in the variable after it increments (and is thus atomic in
nature in terms of increment and save).
D. Assembly operation 6 and 9. This is the call to our static construct System.out.println
followed by the call to load the assembly variable 1 back onto the operand stack so that the
System.out.println statement call can read it.

The line number table in the figure actually shows which line in Java code maps to which line in
disassembled code. Because of this problem the read, increment and get operations can
interleave over each other in a multithreaded setup thus giving wrong results. This read,
increment and get instruction set is actually a type of compound operation at a fine grained level
(byte code level) that needs to be made as a single atomic operation. Though in some cases this
may be acceptable as most software give a fault tolerant guarantee to about 98-99% of operations
but sometimes this may not be acceptable. Its far better to understand and fix such issues than
leave them to luck. It would be a nightmare if by chance you bought your favorite expensive
shopping item from an online checkout and invariably ended up paying for two or three pieces
when you only opted for one.

Race Conditions
Compound operations create a situation called race conditions in a multi threaded setup. Such
race conditions are not present in a single thread model but can only be seen when many threads
work concurrently. Race condition occurs when the correctness of the computation of a Thread
depends highly on its relative timing and its interleaving or scheduling characteristics relative to
other threads. We may get lucky 95% of times and the 5% of times when it fails would probably
be in a production environment.

Race conditions are not exactly the same as data races. Data races involve incorrect data access
because of wrong data/coding semantics most of the times. When the programmer forgets to use
proper synchronization blocks or leaks the state objects directly we end up with data races. Race
conditions on the other hand happen largely because of the context switching choices that the
underlying operating system or platform makes. Race conditions is essentially an undesirable by
product of Operating Systems going advanced and efficient by employing more finer level
parallelism at processor and multi core levels.

To solve our atomic increment problem in the previous section, we can employ the use of
AtomicInteger class and fall back on its getAndIncrement() method to safely increment our
variable without any further synchronization. AtomicInteger is one of the atomic operation
classes introduced in the new java.util.concurrent.atomic package. It uses CAS operation
semantics to achieve atomicity and durability in the increment operation. We shall discuss CAS
operations and instruction set when we talk through our advanced session on concurrency.

Compound Operations
We saw about one type of race condition in our previous section and also how to fix that problem
using an AtomicInteger. But what if we have two such counters or variables?

Consider the following code example.


1
2
3 @NotThreadSafe
4 public class ConnectionPoolWatchDog1 {
5
6 private AtomicInteger borrowers; //we increment this counter
private AtomicInteger connections; //we decrement thsi counter
7
8 public ConnectionPoolWatchDog1() {
9 this.borrowers = new AtomicInteger(1);
10 this.connections = new AtomicInteger(10);
11 }
12
public void borrowOne() {
13
//do some tasks
14 //increment the borrowers count
15 this.borrowers.getAndIncrement();
16 //decrement the remaining conenction count
17 this.connections.getAndDecrement();
//do some other tasks
18 }
19
20 public void returnOne(){
21 //do some tasks
22 //increment the remaining conenction count
23 this.connections.getAndIncrement();
//decrement the borrowers count
24 this.borrowers.getAndDecrement();
25 //do some other tasks
26 }
27}
28
29

The ConnectionPoolWatchDog1 has 2 values to keep track of. The number of connections left
with it which it can give to its callers and the number of callers who have already borrowed a
connection. We could track both of these with a single variable but then what happens if a
connection is not borrowed and also not available for leasing out, probably because its
dependent socket is blocked or non-responsive. So its safe to use two counters to track this.

Now these two counters (borrowers and connections) need to be incremented and
decremented in one atomic operation. So we resort to an AtomicInteger here also. But then the
atomic variable is only mutually exclusive in context of one operation done on it (increment or
decrement). So even with using the atomic variables for both the counters we still cannot achieve
a thread safe setup because its possible that while one thread is on line 15 decrementing for a
borrow operation another thread may decide to return a connection and invoke the statement on
line 24.

It is important to note that lines 15 and 26 are mutually exclusive as they both operate on the
same variable (borrowers). So are lines 17 and 24. But together they are not, since they can
interleave with each other and possibility of a race condition (and even a data race) exists. So to
preserver the thread safety of this code we need to make sure that related variables are updated in
a single indivisible atomic operation.

To solve this problem we have to rely on plain old locking idioms.

Locking
Locking is a mechanism to explicitly and intentionally make a certain part of code single
threaded in nature even when it is run in a multi threaded setup. By employing locking we
intentionally restrict multiple threads from accessing some code flow concurrently thus
restricting the possibility of data mutation by multiple threads simultaneously. There are 2 types
of locking idioms in Java:

Intrinsic locks: These are also called monitor locks. This locking idiom relies on the JVM
guarantee that only 1 thread can ever own a lock on an object. While the object is locked
by a thread, all other interested threads wait for the lock to be opened. The se waiting
threads are not allowed to pursue some other work while they wait. Until the active
thread releases the lock all waiting threads suspend their working.
Extrinsic locks: These are custom made synchronizers which can be used to influence the
locking behavior in code. Java offers a custom java.util.concurrent.locks.Lock
interface to implement more extensive locking operations. Extrinsic locking idioms allow
more fine grained control over the operations, as against intrinsic locks, since the
operation can be spread across and performed until the unlock action is called on the
associated Lock object. Extrinsic locks are discussed in more detail in the advanced
session.

Intrinsic locks are essentially implemented in java using the synchronized keyword. When used
in the method signature it synchronizes the whole method against the lock of the this object.
When used as a block it synchronized the block code against the lock of the object passed to it as
a parameter. ConnectionPoolWatchDog2 solves its thread safety problem by using a
synchronized block and locking on the this instance as shown below.

1 @ThreadSafe
2 public class ConnectionPoolWatchDog2 {
//we increment this counter
3 @GuardedBy("this") private AtomicInteger borrowers;
4
5 //we decrement this counter
6 @GuardedBy("this") private AtomicInteger connections;
7
8 public ConnectionPoolWatchDog2() {
9 this.borrowers = new AtomicInteger(1);
this.connections = new AtomicInteger(10);
10 }
11
12 public void borrowOne() {
13 //do some tasks
14 synchronized(this){
15 //increment the borrowers count
this.borrowers.getAndIncrement();
16 //decrement the remaining conenction count
17 this.connections.getAndDecrement();
18 }
19 //do some other tasks
}
20
21 public void returnOne(){
22 //do some tasks
23 synchronized(this){
24 //increment the remaining conenction count
25 this.connections.getAndIncrement();
//decrement the borrowers count
26 this.borrowers.getAndDecrement();
27 }
28 //do some other tasks
29 }
30}
31
32
33
34
35

Because the currently active Thread locks out other Threads from gaining access on the object on
which synchronized is called out, we say that the thread has locked the object and not the other
way round. It just the same corollary of booking a hotel room for a night. We book the hotel
room and while we stay in that hotel room other customers have to wait it out till we relinquish
the lock on the hotel room. A hotel room is like a code block that is synchronized. Only one
customer (Thread) can stay in it (run through it) at a given time. We book the room with the
hotel, we pay the hotel for the room not the other way round, just as we lock the object for access
to synchronized block. When we are done with the room, we relinquish its lock (exit the
synchronized block) and its then that others can see the state of the room and if needed book it.

It is important to understand that while a thread holds the lock, other threads waiting for that lock
dont see any changes made to the state by the active thread. This is true even if the active thread
is more than the half way through with the synchronized block or even if its on the last
executable statement in the synchronized block or method. Its only when the active thread exits
the synchronized block or method, that the waiting threads come alive and see what changes
actually happened.

However this is not true for threads waiting on different locks. If a Thread T1 is locked on Obj1
and is making changes to a List employees, threads that are blocking on the lock of Obj1 will
not be able to see these changes until the thread T1 exits the lock. However for a Thread T2
locked on some other Obj2 or not locked on anything, can still see these changes as they happen.
So while T1 is executing the employees list mutation changes inside the synchronized block T2
can see them all as they happen because its not blocked on the lock which T1 has acquired and if
free to do what it wants. So if a synchronized block is needed to guard access to a variable or
state, then it is important to ensure that all operations to that state everywhere in code must be
guarded on the same lock provider or object. When a class has invariants that involves a tight
coupling between more than one variable or state holder it is important to ensure that locks are
owned consistently on the same object everywhere. Without this thread safety can be
compromised.

Reentrancy
Reentrancy is actually an Operating System concept of making the processes and process shared
stack reentrant to different processes for effective and block free IPC. Java also borrows this
technique from there and implements this on finer grains object intrinsic lock mechanism.

When a thread obtains a lock on an object all other threads requesting that lock wait or
essentially block on the object. When the original thread releases the lock other threads can
acquire the lock again. This is because intrinsic locks are reentrant. Thus intrinsic locks are by
nature acquired on a per thread basis rather than per request basis. This gives rise to a concept of
reentrant synchronization. Because a thread can acquire a lock it already owns we call it
reentrant synchronization. Without this a Thread would deadlock on itself.

1
2 public class Temp2 {
3 private int age = 10;
4 private synchronized void hello(String name, int age){
String temp = name + " there";
5 synchronized(this){
6 this.age = age;
7 }
8 System.out.println(temp + " age " + age);
9 }
10
public static void main(String[] args){
11 Temp2 t2 = new Temp2();
12 t2.hello("user", 20);
13 }
14}
15

The above code demonstrated the concept of reentrant synchronization. Below figure is the
disassembled version of above code.
Lets walk through the sample output of disassembled code.

A. Shows the ACC_SYNCHRONIZED flag. The JVM automatically enters the monitor on the this
object when it encounters this flag.

B. This is a monitorenter instruction set. It enters the monitor on the variable popped at point
C. in the diagram which happens to be our object. The LocalVariableTable shows the java object
ref/variable mapping with the assembly variable mapping.

D. Shows the monitorexit instruction. After this instruction the monitor is again available for
entry by any other thread.

Reentrancy facilitates the java OOP principle of encapsulation but at the locking mechanism
level. Without reentrant behaviors threads can deadlock as the waiting threads would never get
the change to own the lock once its already taken.

State Visibility Guarantees


Locking idioms not just helps us in controlling access around program critical paths but also
allows us to coordinate access and guarantee consistency and durability of sate visibility
operations. This is an important consideration which JVM specification offers as a subtle
guarantee. Without this guarantee there would actually be little or no sense in actually employing
synchronization to control thread access operations on shared data. The JVM specs guarantee
that while a thread is blocked waiting for the lock, since another thread is using it, it does not see
any changes to the state invariants until the block is opened. Once the blocking thread owns the
lock, it sees all and complete changes that the previous thread made to the shared invariants.

Essentially this is just a more technical wording for a plain simple common sense operation. If
you write something to a variable and read it afterwards then presuming no other write operation
happened or is in progress you should see the same value in the variable which was earlier
written out. Though this seems commonsense enough but its true only in single threaded model.
In multithreaded setup without synchronization there can be many variations that can make it
totally untrue. So locking is not just about making a group of actions atomic with respect to
thread interaction (mutual exclusion) but also about ensuring that threads (other waiting threads
and even itself) see the most up to date state of shared data (visibility).

Java Memory Model offers a happens before relationship guarantee which ensures that state
changes happen correctly and new changes overwrite the old ones consistently and in an
idempotent manner. Java Memory Model however stresses on two important state guarantees
which the class designers must understand.

Word Tearing Phenomenon


Volatile modifier

Word Tearing Phenomenon


Word tearing is a significant aspect of JVM implementations which every developer needs to be
aware of. Essentially the java specification and memory model explicitly talk about this pitfall
that is directly related to processor architectures and behaviors.

From a JVM implementation perspective (and not a Java Programs perspective) the
specification states that every field (a memory address and its associated offset), including array
elements placements, are distinct and mutually exclusive. This means that any update operation
to a field address is mutually exclusive to any other update operation that precedes or succeeds
this operation. Two threads that update adjacent elements of an array separately must not
interfere or interact and do not need synchronization to ensure sequential consistency. In essence
every field operation is atomic in itself.

However some processor architectures dont provide a single atomic machine set instruction to
write to a single byte if the variable length is more than that. On such platforms an update to a
byte array is actually a compound operation involving:

reading the whole word first


updating the appropriate byte offset
writing the whole word back

This operation is illegal as per JVM specs because in a multithreaded setup where
unsynchronized code is updating the array in 2 threads, one thread may see stale array state while
another thread is updating it. This is called as word tearing. Most of the 32 bit processor
platforms suffer from this anomaly though not all. All java types which require at the most 32
bits of storage space for correctly holding their values san be safe written and read in one atomic
operation. However types with length more than 32 bits e.g. Long and Double and array types
which are of 64 bit length, are not safe as their write operations constitute two 32 bit writes in
quick succession. JVM specs calls this as non-atomic writes. Though most of modern 64-bit
platforms dont suffer from this problem but still JVM specs tries to be on the safe side here and
explicitly states that:

Writes to and reads of references are always atomic, regardless of whether they are
implemented as 32-bit or 64-bit values.
Writes to and reads of primitives with size up to 32-bits is atomic.
Writes to and reads of primitives and arrays with size more than 32-bits is non-atomic
unless they are explicitly stated as volatile.

Volatile Modifier
Volatile is an alternate weaker form of synchronization that Java provides to supplement intrinsic
locking. While intrinsic locking works and is used at a macro level in the Java programming
model i.e. in high level Java source code, volatile performs the same function partially at a micro
level i.e. at the processor or machine set execution level. Thats why volatile is not used with
methods or classes but only with variables or fields.

When a field is declared as volatile, the JVM and runtime are directed that:

The said variable is a shared variable and most likely would be involved in a multi-
threaded setup.
The said variable should not be cached in any processor L1 or L2 caches or local registers
but instead always re-read directly from the memory location where it is saved.
The JVM and runtime should not reorder instruction execution of statements around the
volatile variable.

The following code example can fail.

1 public class Temp3 {


2
3 private boolean isReady;
4
public static void main(String[] args) {
5 Temp3 t3 = new Temp3();
6 while(!t3.isReady){
7 try {
8 System.out.println("Not ready dear.");
9 Thread.sleep(1000);
10 } catch (InterruptedException ex) {
ex.printStackTrace();
11 }
12 }
13 }
14}
15
16

The current thread checks for the variable isReady and if not true goes to sleep for 1 sec and
retries again. Though this would work perfectly on a single processor platform (even with
multiple threads in code) but on a multi-processor platform with multiple threads running in code
the call to t3.isReady at A. can actually be cached in processor local registers. So if another
thread updated isReady field the waiting thread may not know and could loop forever since it
prefers the view of the variable value in processors instead of whats there in memory. Making
the variable volatile solves this problem. Thus volatile modifier ensures visibility guarantees for
the variable on which it is declared.

Volatile ensures that all competing threads see the most up to date value of the variable that was
last written to it. If a thread wants to read the variable but it is being written at the moment the
thread waits and once the write finishes the read proceeds to read the latest value. If the writing
thread is queued up after read, then the read proceeds and see the value that is up to date at the
moment. In this essence writes to a volatile variable mimic a monitor exit action (exiting a
synchronized block) and reads to a volatile variable mimic a monitor entry action (entering a
synchronized block). Thats why sometimes volatile is called as half synchronization. This
nature of volatile makes it an excellent tool to prevent word tearing problems. Since reads would
always see the most updated writes so volatile doubles and longs are safe to be used in multi-
threaded setups even on 32 bit platforms because the JVM runtime would not move ahead until
the whole word is read in or modified in one go.

Design Thread Safe Classes and Components


Designing thread safe classes is not a herculean task but rather a simple play by the book set of
rules to be followed and adhered to. This section outlines a set of basic guidelines to follow to
design thread safe classes. As long as we stick to basic OOP principles of encapsulation and
abstraction Thread safe class construction is not a big deal.

Constructing thread safe classes and components involves two things to know and care about:

Design principles: These principles relate about what you should and should not do while
designing, coding and refactoring thread safe classes or components. At a high level these
principles can be divided into instance confinement strategies and thread confinement
design principles.
Documentation principles: These principles advise to be explicitly clear and forth coming
about the synchronization policies of the class or component. Typically these principles
advise us to clearly answer questions like What the class is intended to do? How does it
do it ? What considerations and traps should its clients or callers be aware of? or the
synchronization policies employed by the class

Design Principles Shared State Ownership


One of the primary rules to ensure thread safety is to outline shared state ownership rules. These
rules typically answer the following questions without any reservations:

Who owns the shared state


Who can mutate this shared state and how
Who can access this shared state without locking and how
Who should lock and wait while the state updates

When designing thread safe classes it is always best to not rely on clients or callers of you
classes and objects to provide synchronized access to state mutation operations. Because the
clients may not be fully aware of what state mutates and when they may eventually wrongly
synchronize their calling code which can impact thread safety of overall application. This is a
common problem in the Synchronized Collections API which are created using the
Collections.synchronized API call. The collections returned by Collections.synchronized
API calls actually use the decorator pattern to add synchronization on top of existing Collections
constructs making the existing collection operations atomic. This means that writes and reads are
atomic within themselves. However for client programs which use these collections there are
always compound invariants which involve a read, mutate and write operation on these
collections which also should be atomic. So the following code may seem harmless in a single
threaded setup but would fail in a multi threaded model.

1 public class EmployeeManager3 {


2
3 private Map<Integer, Employee> employees =
4 Collections.synchronizedMap(new HashMap<Integer,
Employee>());
5
6 public void addNewEmployee(Employee employee) {
7 this.employees.put(employee.getEmployeeId(), employee);
8 }
9
10 public boolean updateEmployee(Employee employee) {
if (this.employees.containsKey(employee.getEmployeeId())) {
11 this.employees.put(employee.getEmployeeId(), employee);
12 return true;
13 } else {
14 return false;
15 }
}
16
17 public boolean deleteEmployee(Employee employee) {
18 if (this.employees.containsKey(employee.getEmployeeId())) {
19 this.employees.remove(employee.getEmployeeId());
20 return true;
21 } else {
22 return false;
}
23 }
24
25 public Employee getEmployee(int employeeId) {
26 if (this.employees.containsKey(employeeId)) {
27 return this.employees.get(employeeId);
} else {
28 return null;
29 }
30 }
31}
32
33
34
35

The addNewEmployee, updateEmployee, deleteEmployee and getEmployee methods are not


synchronized within their own context but rely on the synchronization aspects provided by the
Collections.synchronized API. Now assuming two threads are working together to update the
same employee and read it in parallel. So while thread 1 reaches line 30 and receives the
employee thread 2 is in process of updating the same guy. This could lead to stale data. Image
the same scenario but this time one thread is reading the employee and another thread is trying to
delete it. So while the reading thread has completed the contains statement at line 29 and found
the employee exists the deleting thread executes the line 21 and deletes it.

To fix these problems we need to synchronize the EmployeeManager to allow only 1 operation at
a time. How bout this?

public class EmployeeManager4 {


1
2 private Map<Integer, Employee> employees =
3 Collections.synchronizedMap(new HashMap<Integer,
4 Employee>());
5
6 public synchronized void addNewEmployee(Employee employee) {
this.employees.put(employee.getEmployeeId(), employee);
7 }
8
9 public synchronized boolean updateEmployee(Employee employee) {
10 if (this.employees.containsKey(employee.getEmployeeId())) {
11 this.employees.put(employee.getEmployeeId(), employee);
12 return true;
} else {
13 return false;
14 }
15 }
16
17 public synchronized boolean deleteEmployee(Employee employee) {
if (this.employees.containsKey(employee.getEmployeeId())) {
18 this.employees.remove(employee.getEmployeeId());
19 return true;
20 } else {
return false;
21 }
22 }
23
24 public synchronized Employee getEmployee(int employeeId) {
25 if (this.employees.containsKey(employeeId)) {
return this.employees.get(employeeId);
26 } else {
27 return null;
28 }
29 }
30}
31
32
33
34
35

is this class thread safe now? The answer is No.

Why?

Because this class synchronizes on this object where as it should synchronize on employees.
This is what the Javadocs for Collections.synchronizedMap state.

This means that internally in the employees the synchronization is based on the lock of the
underlying map. But in our client class EmployeeManager it is based on the instance of
EmployeeManager represented by this. Clearly these are two different objects and thus threads
willing for locks on these objects wont block each other. Also if employees is accessed from a
subclass of EmployeeManager then synchronized on this wont help in blocking the access
either. Its the map operations which we need to make atomic not our own code. So we must
synchronize on the employees variable instead of this.

The following code example shows it correctly:


1
2
3
public class EmployeeManager5 {
4
5 // private final Map<Integer, Employee> employees =
6 // Collections.synchronizedMap(new HashMap<Integer,
7 Employee>());
8
9 private Map<Integer, Employee> employees =
Collections.synchronizedMap(new HashMap<Integer,
10Employee>());
11
12 public void addNewEmployee(Employee employee) {
13 synchronized(employees){
14 this.employees.put(employee.getEmployeeId(), employee);
15 }
}
16
17 public boolean updateEmployee(Employee employee) {
18 synchronized(employees){
19 if (this.employees.containsKey(employee.getEmployeeId())) {
20 this.employees.put(employee.getEmployeeId(), employee);
return true;
21
} else {
22 return false;
23 }
24 }
25 }
26
public boolean deleteEmployee(Employee employee) {
27 synchronized(employees){
28 if (this.employees.containsKey(employee.getEmployeeId())) {
29 this.employees.remove(employee.getEmployeeId());
30 return true;
31 } else {
return false;
32 }
33 }
34 }
35
36 public Employee getEmployee(int employeeId) {
synchronized(employees){
37 if (this.employees.containsKey(employeeId)) {
38 return this.employees.get(employeeId);
39 } else {
40 return null;
41 }
}
42 }
43
44
45
This is the right way to do it. This was an example where incorrect synchronization policies and
half-baked state ownership rules play havoc.

Design Principles Instance Confinement


Instance confinement is a technique which uses encapsulation and a couple of design pattern
para-diagrams to restrict access to shared mutable data. This technique instills the discipline to
make the encapsulating class or its subclass the owner of shared mutable data and does not allow
direct data mutation from outside. In some cases a limited mutation may be allowed but is
controlled using thread confinement techniques.

EmployeeManager5 is a good example of an instance confined thread safe class (though not
100%).

All operations on the employees is encapsulated inside.


EmployeeManager5 is about 95% thread because its methods addNewEmployee,
updateEmployee, deleteEmployee are thread safe.
The getEmployee is not 100% thread safe as it lets a live Employee object escape from
the EmployeeManager5 class. To fix this we should make a copy of the employee once it
is received form the map and then return that copy.
EmployeeManager5 does not handle serialization effectively.

Instance confinement is used heavily in the Collections API to make synchronized counter parts
of normal Collections like HashMap and Lists. They actually make use of a decorator pattern to
create a synchronized version of the collection and keep the synchronized version classes as
private static inner classes so that these class instances cant escape. Instance confinement makes
it easy to construct thread safe classes as the only class to be analyzed for thread safety is the
owner class. Without this analyzing thread safety in a big project can become a nightmare.

Instance confinement is largely done using the design techniques of

Delegation
Composition
Private Monitor Pattern

Instance Confinement Delegation


Delegation thread safety principle promotes use of existing thread safe constructs and encourages
the main classes to delegate the thread safety work to existing thread safe classes instead of
making their own. The idea is simply to use what you can (and should) and create what you
cant. Since we use the thread safety guarantees offer by existing classes and constructs we dont
need thread safe or locking idioms in our code.

Using this principle our EmployeeManager5 could be better off to use a ConcurrenHashMap
instead of a synchronizedMap and delegate all its check if it contains and then mutate
operations to atomic putIfAbsent. Also the get operation on ConcurrenHashMap is atomic
about contains and get mechanism. So by using a ConcurrenHashMap we can eliminate the
need for contains check in our EmployeeManager5 code.

Using delegation also has another advantage. It eliminates the need for locking in our code.
Since in the above example we rely on ConcurrenHashMap now so we can eliminate the
synchronized keyword and locking idioms from our code and thus make it lock free with respect
to our instance scope. This also eliminates the issue of thread blocking on each other due to
synchronized block locks.

Delegating thread safety works when we dont have dependent shared mutable state variables to
take care of. E.g. ConnectionPoolWatchDog2 (see previous code example in Locking section)
cannot be made thread safe by delegation alone. Since it involves two shared invariants that are
dependent on each other, so some form of client side locking is essential though the two
invariant types are themselves thread safe.

Instance Confinement Composition


Delegation thread safety principle owns its roots to another Gang Of Four (GOF) prevalent
design principle named as Composition. In simple terms, GOF principles encourage us to make
abundant use of composition as against inheritance to add functionality and behavior.

Lets presume we want to add a new behavior getIfPresent to a HashMap. There are two
ways to do this.

Approach 1 Inheritance

Create a new interface type CustomMap which extends Map which adds the new
behavior getIfPresent
Extend HashMap to make a CustomHashMap which implements all the same interfaces
which a HashMap except Map. Instead of Map interface we implement the CustomMap.
Add the method implementation for the new behavior.

Approach 2 Composition

Create a new interface type CustomMap which extends Map which adds the new
behavior getIfPresent
We create a private instance variable of type HashMap in our CustomMap instead of
extending HashMap.
We implement the new behavior getIfPresent in our CustomhashMap class.
But for all existing Map methods or actions we just delegate to the private HashMap
instance.

As discussed earlier, synchronized collections in the Collection API make use of


Approach 2 to make all existing collection types thread safe. Inheritance approach seems
good and viable when you have a few behaviors to add and new behaviors are not
actually an atomic view of existing compound behaviours. e.g. getIfPresent is actually a
compound of if contains then get. When we need to add many of such new behaviors
its better to use composition instead of inheritance.

Sometimes again grouping such objects types using inheritance may not actually be
abiding to the OOP principles. E.g. a car may need a behavior replaceIfCustomerLikes
for its seats and upholstery. Adding this behavior to Automobile super type using
inheritance may not be a good idea as such a behavior is not a generic one which an
automobile exhibits. Its an invariant dependent on the owner of a car.

Thread safety also works on the same lines.

Private Monitor Pattern


Private monitor pattern, also called java monitor pattern, is a direct derivative to the
encapsulation principle. Normally the strict encapsulation principles applied to data variables is
to hold them as private instance variables instead of public or protected. This allows the class
instance to encapsulate the data it owns. Secondly to allow selective mutation of data variables
and free viewing of the current data variable state, the class can expose public accessors and
mutator methods. The mutator methods can implement conditional logic to selectively mutate the
state values.

Now extend this principle to an java.lang.Object instance stored in the class, as instance
variable, that is intended to be used as the exclusive lock provider for all operations on the
instance. Now if we dont allow a reference to this to escape during instance construction, we
achieve a perfectly thread safe class. This is shown in the following code example.

1 @ThreadSafe
2 public class EmployeeManager6 {
private List<Employee> emplyees;
3 private final Object lockMonitor = new Object();
4
5 public EmployeeManager6(){
6 this.emplyees = new ArrayList<Employee>();
7 }
8
9 public Employee getEmployee(int index)
throws CloneNotSupportedException {
10 synchronized(this.lockMonitor){
11 return (Employee)(this.emplyees.get(index)).clone();
12 }
13 }
14
public void addEmployee(Employee employee) {
15 synchronized(this.lockMonitor){
16 this.emplyees.add(employee);
17 }
18 }
19
20 public void deleteEmployee(int employeeId) {
21 synchronized(this.lockMonitor){
for (Iterator<Employee> it = emplyees.iterator();
22it.hasNext();) {
23 Employee emp = it.next();
24 if(employeeId == emp.getEmployeeId()){
25 it.remove();
break;
26 }
27 }
28 }
29 }
30
31 public void deleteEmployee(Employee employee) {
synchronized(this.lockMonitor){
32 this.emplyees.remove(employee);
33 }
34 }
35
36 /*
* returns an unmodifiable list.
37 * Can also return a copy of the original list.
38 *
39 */
40 public List<Employee> getAllEmployees(){
41 return Collections.unmodifiableList(this.emplyees);
}
42}
43
44
45
46
47
48
49

Since all the methods bodies that need to maintain exclusive thread access use only the
lockMonitor object, so no two synchronized blocks can ever race against each other. Also the
monitor is declared as final so the the reference lockMonitor does not accidently change its
target object. As we shall see in the section about final modifier, such an action can have very
wrong impact on an otherwise perfectly thread safe class. Further more since the lockMonitor
object is not exposed to outside world no one can accidently modify it or alter it. Client of
EmployeeManager6 dont need to take any additional synchronization steps as long as they dont
try to derive operations new operations by combining existing operations of EmployeeManager6
. Responsibility of such new operations should be shouldered by the EmployeeManager6 class.

The following code block shows an attempt by a client to create a compound operation out of
methods exposed by EmployeeManager6 .

public class EmployeeManager6Client {


1 private EmployeeManager6 employeeManager6;
2
3 public EmployeeManager6Client(){
4 this.employeeManager6 = new EmployeeManager6();
}
5
6 public void deleteEmployeeRecord(int employeeId){
7 try {
8 Employee employee =
9 this.employeeManager6.getEmployee(employeeId);
this.employeeManager6.deleteEmployee(employee);
10 } catch (CloneNotSupportedException ex) {
11 ex.printStackTrace();
12 }
13 }
14 }
15
16

The operation deleteEmployeeRecord is not thread safe, though its two invariant operations
themselves are. This is because there is a margin of possibility for race situation when the code
flow make a transition between the calls of getEmployee and deleteEmployee on
EmployeeManager6 instance as shown below by the disassembled code below.

But the worst part is that EmployeeManager6Client cant do anything about it. If it would
attempt to synchronize the deleteEmployeeRecord method on its own it would fail equally
miserably. Why?

This is because the invariant operations getEmployee and deleteEmployee are actually
synchronized on the lock which is provided by the lockMonitor object and this lockMonitor
object is fully encapsulated inside the EmployeeManager6 class instance. So believing that it
would be a bad practice to add a getter for lockMonitor in EmployeeManager6 class, the only
option left for us to follow is the right choice here, and that is to let EmployeeManager6 should
the responsibility to implement this method inside it and expose the implementation in its public
contract.

Thread Confinement
Sharing mutable data requires correct synchronization mechanisms, failing which the results can
be dangerous. One way to avoid this is to not share the mutable data directly. If we can ensure
that only one thread ever accesses the mutable state then we dont need synchronization at all to
manage the data mutation problems. This philosophy is called as thread confinement. There are a
couple of ways to do this as subsequent sections explain.

Thread Confinement Implementation Owned


As discussed earlier, proper encapsulation and abstraction principles ensure that mutable data is
never escaped form the implementation classes or components. When the implementation of
frameworks and APIs fully own the responsibilities of keeping data thread safe under all
circumstances, it becomes naturally easy for their clients to work through the code. The
implementations should also ensure that data serialization semantics does not garble the data
sanity. Serialization mechanisms if followed wrongly can create thread safety hazards in the
surfaced objects. Since serialization would create a new copy of our original object so we need to
make sure that the new cop is also thread safe. Inheritance is another scenario that
implementations need to take care of. Subclasses can easily override the super class methods and
play havoc with the state data if the state is not corrected encapsulated and hidden. The
implementations should ensure that subclasses dont get direct control to mutate the shared
invariants.

Thread Confinement Thread Stack Confined


This is a special type of thread confinement where the state can only be reached through the local
variables since the local variables which the thread creates are incidentally confined to only that
threads execution stack. One example of this is method parameters and their copies within a
method. Another example is the variour local variables which we define inside blocks of code.

Consider the following example screenshot.


In the adjoining example the local variable tempEmployee is totally thread safe by design. Since
all threads entering the method updateEmployee would own their own copies of
tempEmployee so two threads would never cross each other on this. We cannot violate its thread
safety even if we want to.

Another thing to note here is that the caller of this method passes the employee variable by
reference, so it still has a mutating handle on the employee. If we dont create a local variable
out of this employee , there can be a situation where the check on containsKey passes, but at
that very moment the caller of this method changes the employeeId of the associated
corresponding employee object. Its always a good practice to make the method parameter
references final and make a copy of mutable parameters before actually proceeding to work with
them.

Thread Confinement Working with safe copies


Safe copies, also called as Shared Thread Safe Copies, extend the Thread Stack confinement idea
to a bit bigger level. Same principles apply but at the inter class or inter component data sharing
level. The previous code example above made use of clone method to create a copy of the
employee parameter before analyzing it in the employees List. This is essentially the use of
prototype pattern. Another beautiful use of the same idea is shown in the code example below
where we read the employee from the list and return it to the caller..

/*
01 * This is the right way to get data from collections.
02 * Finding by index is not safe as index may change over time.
03 */
04 public Employee getEmployee(String name)
throws CloneNotSupportedException{
05 //get the employee from the list
06 Employee employee = this.findEmployeeByName(name);
07 if(employee != null){
return (Employee)(employee.clone());
08 }else{
09 return null;
10 }
11 }
12
13
14

The example code here gives an effective example of creating a safe working copy. The method
returns a working copy of the employee which it fetches form an internal list. The clients of this
method use the working copy of this employee object instead of a direct reference to the
employee which his in the list. Even if the clients change the returned employee object, the
original employee in the list is not modified and thus the invariant state is not altered. It is
important to note that the Employee object returned by the method is not immutable in nature.
Clients can still make changes to the same object. Its just that those changes dont find their way
back in the list unless someone tried to update the employee again.

Thread Confinement Thread Local copies


TheadLocal is a more API inclined way of dealing with Thread confinement design. Java SDK
offers excellent API semantics to make variables and state thread inclined using the TheadLocal
class. Variables that are declared as TheadLocal are essentially local to each thread scope which
tries to access them. This means that each thread which tried to access them has its own copy of
the variable on which it works and this copy is private to the threads scope. So threads dont
share the same TheadLocal variable but make copies of it, for their own use. This also
consequently means that Threads cannot influence or mutate TheadLocal variable present inside
other threads. This makes it a wonderful thread confinement mechanism. TheadLocal instances
are typically private static fields in classes because it makes no sense to declare them as
instance variables.

TheadLocal is used exhaustively in common middleware technologies like JMS, stateful


connection pools, message dispatchers etc. One of the most important and frequent use of
TheadLocal is for random number generation for use in security round robins and database
primary key generation. The following code example inspired by the TheadLocal JDK API
Javadocs shows a prominent use of TheadLocal.

public class SafeCounter {


1 // Atomic integer containing the next thread ID to be assigned
2 private static final AtomicInteger nextId = new AtomicInteger(0);
3
4 // Thread local variable containing each thread's ID
5 private static final ThreadLocal<Integer> threadId =
6 new ThreadLocal<Integer>() {
@Override
7 protected Integer initialValue() {
8 return nextId.getAndIncrement();
9 }
};
10
11 // Returns the current thread's unique ID, assigning it if necessary
12 public static int get() {
13 return threadId.get();
14 }
15}
16
17
18

//TODO: Explain the code above a bit.

Another common use of TheadLocal was in HibernateUtils during the times of Hibernate 2 days.
To make use of Hibernate then you were required to created a Utility class that would hold the
Hibernate session factory and return newly created session objects to its callers. Part of this
utility is shown below which illustrates the use of TheadLocal .

1 public class HibernateUtil {


2 private static final Log log = LogFactory.getLog(HibernateUtil.class);
3 /**
4 * Read the configuration, will share across threads*
5 */
6 private static SessionFactory sessionFactory;
/**
7 * the per thread session *
8 */
9 private static final ThreadLocal<Session> currentSession = new
10ThreadLocal<Session>();
/**
11
* The constants for describing the ownerships *
12 */
13 private static final Owner trueOwner = new Owner(true);
14 private static final Owner fakeOwner = new Owner(false);
15 /**
* set this to false to test with JUnit *
16 */
17 private static final boolean isLife = true;
18
19 /**
20 * get the hibernate session and set it on the thread local. Returns
21 * trueOwner if it actually opens a session
*/
22 public static Object createSession() throws Exception {
23 Session session = (Session) currentSession.get();
24 //System.out.println(session);
25 if (session == null) {
//System.out.println("No Session Found - Create and give
26the identity");
27 session = getSessionFactory().openSession();
28 currentSession.set(session);
29 return trueOwner;
}
30 //System.out.println("Session Found - Give a Fake
31identity");
32 return fakeOwner;
33 }
34
35
36
37

Use of TheadLocal has two primary limitations.

State Sharing Only

One common pattern that we can see in classes that make use of TheadLocal effectively,
is that the classes themselves are not interested in the TheadLocal data.
They are actually interested in sharing that data. E.g. RandomNumber generator doesnt
consume the number itself. It gives those numbers to its callers to use. Same is the case
for HibernateUtils too. It just creates the session and gives it to its callers. Similar
structure is also prevalent in connection pool designs.
So thread locals make effective sense only in such situations

Managed Thread Pools

Another issue which TheadLocals have is related to application relying on heavy Thread
Pooling. TheadLocal can be very dangerous when it comes to long running applications
and garbage collections especially in server applications.
After reading the TheadLocal API and Javadocs it can be assessed that the object put in a
TheadLocal context is associated to a particular thread, and will be garbage collected
once the containing thread is dead.
So there is a high risk that the object stored in the thread local may never be garbage
collected when your app runs on a server like Tomcat or WebSphere, which their own
pool of working thread, even when the class that created this TheadLocal instance is
garbage collected. This can lead to memory leaks and connection leaks.
This is the exact problem that happens in Tomcat v7 when we use custom connection
pools which create their own thread locals but rely on tomcat for their thread pool
management requirements.
Tomcat v7 displays a following message (or similar one) in its logs when such a webapp
is undeployed, redeployed or shutdown. This message is for the MySQL driver
ThreadLocal leak.

SEVERE: A web application registered the JBDC driver [com.jdbc.mysql.Driver]


but failed to unregister it when the web application was stopped. To prevent
a memory leak, the JDBC Driver has been forcibly unregistered.
Thread Confinement Immutability and Final
Immutable objects and final references are the two most debated and disputed aspects of Java
programming model. Immutability essentially states that once the object is created and initialized
its internal state cannot be change again. Because its internal state cannot be changed again it
automatically becomes thread safe once it is created. Such an immutable object or defensive
copies, as they are also called, can be passed to untrusted client code which may try to mutate it.
Then again any mutating operation on the immutable object creates a new object to the same
type with the new target state instead of altering the existing one. Thus immutable objects are
always thread-safe.

This post doesnt go into details of creating an immutable object as this is a vast topic in itself.
However a brief guideline is states about the behavior of immutable objects. An object is deemed
immutable if and only if:

It does not allow any public access to mutate its internal state.
It does not allow state mutation using cloning and reverse cloning.
It does not allow state mutation using reflections API.
All its state data is preferable tagged with final modifier.
It does not allow a reference to this to escape during construction

Final modifier on variables plays a fundamental role in ensuring immutable state transition and
also in JVM runtime performance optimizations. Please note that this is not the same as final
modifier on classes and method signatures. While objects can be made immutable as outlined
earlier but still their references are not immutable in nature.

Consider the following code example.

1
2 public class Temp6 {
3 private String name;
4
public String getName() {
5
synchronized(this.name){
6 return name;
7 }
8 }
9
10 public void setName(String name) {
synchronized(this.name){
11 this.name = name;
12 }
13 }
14 }
15

Though name is a String and is immutable in above code and lets say constitutes the shared data
so we synchronize the getter and setter on it. But the String object itself is immutable, this we
know, however the reference name is not. This means we can construct another String object
somewhere in our program and assign the reference name to it and nothing would go wrong, at
least programmatically. This is essentially what the setter does here. But if the object to which
the reference name changes then our synchronized locks fail.

Why?

Because the synchronized(name) code obtains the lock on the String object to which the
reference name points to and not on the reference itself. When a thread T1 calls
synchronized(name) at line 11, it obtains a lock on the String object to which the reference
name points to. But then T1 changes the object pointed to by name on line 12. At that point of
time any other thread T2 or T3 can work through both the methods (get and set) since the object
on which they would obtain a lock would most probably not be the same as the one on which T1
did.

To make Temp6 thread safe we need to declare name as final and provide capability methods or
a factory to make new Temp6 objects as the state of name variable changes. That way the
reference cannot change again. In essence we need to make Temp6 immutable and declare the
reference name as final.

The EmployeeManager5 class which we discussed earlier also suffers form this problem. Since
the synchronized block in the class, synchronizes on the reference employees which is not
final, changing the object to which employees points can break the thread safety of our class.

Because of these reference swapping restriction rules on Final variables we get what is called as
Initialization safety for such variables and their use across code. This allows JVM
implementations to work up some performance optimizations of their own too. Because of the
initialization guarantees for their variables JVM runtimes are free to cache final variables in
processor local L1 and L2 caches. Since these references cannot be shifter from one object to
another, such objects can be cached for quick access with minimal loss to durability.

Guarded By Lock
Most of the design principles outlined so far, work well enough to ensure thread safety of classes
and components. However in some situations these alone may not be enough. In such situations
it becomes a necessity to include some locking mechanism, either intrinsic or extrinsic in
addition to the above techniques.

Though locking provides a fool proof mechanism to ensure thread safety but locking idioms are
essentially blocking in nature. By using locking idioms we intentionally enforces sequential
behavior over the code block that it guards even if there are multiple threads waiting for access.
This is analogous somewhat to what pipes do in Operating System designs. An immediate
impact of this is on the performance of the overall program but keeping lock contention scopes
as minimal as possible, performance bottlenecks can be reduced though never totally eliminated.
All of the other techniques outlined earlier are non-blocking in nature and thus provide much
better performance than intentional locking mechanisms.

Documentation Principles
As much as it is difficult and important to write effective concurrent code, its equally difficult
and far more important to document the behavior of your concurrent code correctly. Most of the
time incorrect multi-threaded code results from incorrect use of library APIs and frameworks.

How many of us know if:

The connection pools that we used in our projects does provide us a thread safe
connection object or not OR
Our own connection factory for pooling the JCR session object provides thread safe
access to JCR session objects for use in our CQ projects OR
Hibernate provides us a Thread safe access to session object.

I know point 3 is true but I dont know about point 1 and 2. This is because the framework
owners or creators didnt document this aspect as effectively as the Hibernate creators did.
Hibernate Javadoc API clearly states this out and any deviations naturally mean a bug in
Hibernate code. So what about point 1 and point 2? If my connection pool does not behave as
expected is that a bug in my code or in the framework.

Honestly there is no end to this argument once it starts. The point to understand here is that
concurrency policies and behaviors for classes should be documented explicitly and clearly. We
need to call out if the clients of our class need to employ synchronization to achieve thread safety
or do we handle it effective in our framework code.
Java Concurrency - Part 1 : Threads
The concurrency is the fact to made several things at the same time using several threads.

A thread, also called Lightweight Process, is treatment unity. Threads executes code in parallel
of each other threads currently running. When you've only one processor, there is a thread
running at the same time of the others, you only have the impression of concurrency (I don't say
it's not useful, I say it's different), but when you've multiple processors, you'll see the power of
multithreading. In this case, you can have your threads distributed on the processors of the
computer.

In Java, a thread is an instance of the class java.lang.Thread. A Thread can be managed in one of
these two ways :

1. Directly mapped to a native thread of the operating system. This is used when the
operating system provide a preemptive threading system.
2. Managed by the virtual machine in a preemptive way.

A preemptive system, is a system in which the threads are managed by a scheduler and can be
interrupted at any time to give processor to an other thread. When you program, you doesn't have
to pay attention of which type of threads you use, the result will normally be the same. But
you've to know that there can differences between operating systems.

There is three very important concepts when doing concurrent programming :

1. Atomicity : An operation is said atomic when it cannot be interrupted. There is almost no


atomic operations in Java, the only we've is the assignation a = 5, but a = b++ is not
atomic. In some cases, you'll have to make atomic some actions with synchronization,
we'll see later how to do that.
2. Visibility : This occurs when a thread must watch the actions of an other threads by
example the termination of the thread. This also implies some kind of synchronization.
3. Order of execution : When you have normal program, all you lines of code run in the
same order every time you launch the application. This is not the case when you make
concurrent programming. You first instruction can followed by an instruction of the
thread B or by the first instruction. And that can change every time you launch the
application. The order of execution is not guaranteed ! I will certainly repeat that
sometimes, but that's important to know.

We'll see these concepts more deeply in the others parts of the set.

Lets start introducing the Thread class in Java. You can create threads in two ways :

1. Extends Thread
2. Implements Runnable and pass an instance of your news class to the Thread constructor
The first solution isn't a good solution because what you're creating is not a new specialized
thread, but several instructions to run in a new Thread, namely a Runnable. Implementing
Runnable is also better because Runnable is an interface and so, you can also extends a class
and implementing Runnable, that's useful in some cases.

In my examples, I'll always use the second way. So let's declare our first Runnable :

public class MyFirstRunnable implements Runnable{


@Override
public void run() {
System.out.println("In a thread");
}
}

And use it to create a new Thread and start it :

Thread thread = new Thread(new MyFirstRunnable());


thread.start();

The Thread will stopped when the end of the run() will be reached. You cannot force a thread to
stop (there is stop() method, but deprecated), we'll see later how to properly stop a thread.

And now, what happens if we add a simple line of code to our program :

Thread thread = new Thread(new MyFirstRunnable());


thread.start();
System.out.println("In the main Thread");

Can you predict the result of this code ? Nobody can't, it's not predictable, you can have :

In a thread
In the main Thread

or

In the main Thread


In a thread

And we cannot do better than that.

You can use the Runnable several times :

Runnable runnable = new MyFirstRunnable();

for(int i = 0; i < 25; i++){


new Thread(runnable).start();
}

Now, 25 threads are launched.


You can also give names to Thread using the setName() method. You can get the name of the
current thread using Thread.currentThread().getName(). Let's do a little example :

public class MySecondRunnable implements Runnable{


@Override
public void run() {
System.out.printf("I'm running in thread %s \n",
Thread.currentThread().getName());
}
}
Runnable runnable = new MySecondRunnable();

for(int i = 0; i < 25; i++){


Thread thread = new Thread(runnable);
thread.setName("Thread " + i);
thread.start();
}

This is the best example to see that the other is unpredictable. Here are two executions on my
machine :

1.

I'm running in thread Thread 0


I'm running in thread Thread 1
I'm running in thread Thread 2
I'm running in thread Thread 3
I'm running in thread Thread 4
I'm running in thread Thread 5
I'm running in thread Thread 7
I'm running in thread Thread 14
I'm running in thread Thread 13
I'm running in thread Thread 12
I'm running in thread Thread 11
I'm running in thread Thread 10
I'm running in thread Thread 9
I'm running in thread Thread 8
I'm running in thread Thread 6
I'm running in thread Thread 15
I'm running in thread Thread 16
I'm running in thread Thread 17
I'm running in thread Thread 18
I'm running in thread Thread 19
I'm running in thread Thread 20
I'm running in thread Thread 21
I'm running in thread Thread 22
I'm running in thread Thread 23
I'm running in thread Thread 24

2.

I'm running in thread Thread 0


I'm running in thread Thread 1
I'm running in thread Thread 2
I'm running in thread Thread 3
I'm running in thread Thread 4
I'm running in thread Thread 5
I'm running in thread Thread 6
I'm running in thread Thread 7
I'm running in thread Thread 8
I'm running in thread Thread 9
I'm running in thread Thread 10
I'm running in thread Thread 11
I'm running in thread Thread 12
I'm running in thread Thread 13
I'm running in thread Thread 14
I'm running in thread Thread 15
I'm running in thread Thread 16
I'm running in thread Thread 17
I'm running in thread Thread 18
I'm running in thread Thread 19
I'm running in thread Thread 20
I'm running in thread Thread 21
I'm running in thread Thread 22
I'm running in thread Thread 23
I'm running in thread Thread 24

Like you can see, the order the threads instructions are executed is not guaranteed at all.

Java Concurrency : Part 2 - Manipulate


Threads
After seeing how to create Threads, we'll see in this article what we can do to manipulate
Threads.

When we've Threads, we can make several operations on the Threads :

Make the current Thread sleeping during x milliseconds


Wait for an other thread to complete
Manage the priorities of Threads and pause a thread to give an other thread the
opportunity to run
Interrupt a thread

We'll now see how to do all these things.

First and easier, we can make a thread sleeping for a certain number of milliseconds. To do that,
the Thread class has a method sleep(long millis). But this method is static, so you can only make
the current Thread sleeping. You cannot choose the thread you want to make sleeping, your only
choice is the current Thread so :

Thread.sleep(1000);
makes the current Thread sleep during 1000 milliseconds (1 second). But, you have to catch an
exception, InterruptedException. This exception occurs if the sleeping thread is interrupted. So
you have to do that :

try {
Thread.sleep(1000);
} catch (InterruptedException e){
e.printStackTrace();
}

But this not the good way to manage the InterruptedException. We'll see in one moment, how to
deal with this exception.

If you want more precision, you can use the overloaded version of sleep that takes the number of
milliseconds plus a certain number of nanoseconds to sleep. The precision of this sleep depends
on the system timers and clocks.

For example, if you want to sleep 1000 milliseconds and 1000 nanoseconds (1 microsecond),
you can do like that :

try {
Thread.sleep(1000, 1000);
} catch (InterruptedException e){
e.printStackTrace();
}

Here is a little example to test that :

public class SleepThread {


public static void main(String[] args) {
System.out.println("Current time millis : " +
System.currentTimeMillis());

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("Current time millis : " +


System.currentTimeMillis());

System.out.println("Nano time : " + System.nanoTime());

try {
Thread.sleep(2, 5000);
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("Nano time : " + System.nanoTime());


}
}
In my computer, this produce this result :

Current time millis : 1273959308480


Current time millis : 1273959309480
Nano time : 5878165216075
Nano time : 5878166730976

You can see that the sleep of milliseconds is very precise, but with nanoseconds the result can
vary a lot. And of course, the result depends of your computer, your operating system and your
configuration.

An other thing, you can do with Threads, is waiting for an other thread to die. For example, you
can create five thread to compute sub result and wait for these 5 threads to finish to compute the
final results based on the results of the five threads. To do that, you can use the join() method of
the Thread class. This method is not static, so you can use it on any thread to wait for it to die.
Like sleep() this method throws InterruptedException in the when the thread is interrupted
during waiting for an other thread. So to wait on thread2, you just have to do that :

try {
thread2.join();
} catch (InterruptedException e){
e.printStackTrace();
}

That will make the current Thread waiting for thread2 to die. You can also add a timeout in
millis, or millis + nanos, with the overloaded versions of join(), join(long millis) and join(long
millis, int nanos). Here is little example that shows all that stuff :

public class JoinThread {


public static void main(String[] args) {
Thread thread2 = new Thread(new WaitRunnable());
Thread thread3 = new Thread(new WaitRunnable());

System.out.println("Current time millis : " +


System.currentTimeMillis());

thread2.start();

try {
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("Current time millis : " +


System.currentTimeMillis());

thread3.start();

try {
thread3.join(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("Current time millis : " +


System.currentTimeMillis());
}

private static class WaitRunnable implements Runnable {


@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

That produce this result on my computer :

Current time millis : 1274015478535


Current time millis : 1274015483538
Current time millis : 1274015484538

You can see that the first join() wait 5 seconds for the other thread and when we set a timeout,
we wait only 1 seconds and return from join method.

When working with Threads, it's also possible to change the priority of a Thread. In the Java
Virtual Machine, the Thread scheduler, use a priority-based scheduling. So if a Thread enter in
Runnable state with a higher priority than the running Thread, the new Thread will run and the
current running thread will return to Runnable state and waits for its turn. But this behavior is not
guaranteed and is completely depending on the virtual machine you are working on. So, do not
rely on thread priorities, just use them to improve efficiency of your program.

Normally, the priority range of Threads is an integer from 0 to 10, but some virtual machine have
lower or higher ranges. To know the range of priority, you can use constants of the Thread class :

public class ThreadPriorityRange {


public static void main(String[] args) {
System.out.println("Minimal priority : " + Thread.MIN_PRIORITY);
System.out.println("Maximal priority : " + Thread.MAX_PRIORITY);
System.out.println("Norm priority : " + Thread.NORM_PRIORITY);
}
}

On my computer, I've the most current values :

Minimal priority : 1
Maximal priority : 10
Norm priority
To set the priority of a Thread, you can use the setPriority(int priority) method of the Thread
class. If you enter a value greater than the maximal priority, the maximal value will be used. If
you don't specify a priority, the used priority, will be the priority of the current Thread.

An other way to works with priority is the yield() method. This method is static, so this works on
the current Thread. The purpose of this method is to make the Thread going to Runnable again
and to give the opportunity to other threads to get their turn. But in practice, the behavior of this
method is not guaranteed. It can be implemented as a no-op on certain systems. It's not easy to
test that in practice, because the results can truly depends on your computer, virtual machine and
operating system. It's a good things to not use the priorities of Threads in practice.

The last thing you can do with a Thread, is to interrupt it. In Java, you have no way to force a
Thread to stop, if the Thread is not well-done, it can continue its execution infinitely. But you
can interrupt a Thread with the interrupt() method. This method interrupt the thread, if the thread
is sleeping or joining an other Thread, an InterruptedException is thrown. You have to know that
if the thread was sleeping or joining, the interrupted status of the Thread will be cleared. Namely,
the method isInterrupted() will return false. A little example to demonstrate that :

public class InterruptThread {


public static void main(String[] args) {
Thread thread1 = new Thread(new WaitRunnable());

thread1.start();

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

thread1.interrupt();
}

private static class WaitRunnable implements Runnable {


@Override
public void run() {
System.out.println("Current time millis : " +
System.currentTimeMillis());

try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("The thread has been interrupted");
System.out.println("The thread is interrupted : " +
Thread.currentThread().isInterrupted());
}

System.out.println("Current time millis : " +


System.currentTimeMillis());
}
}
}
That produce that kind of result :

Current time millis : 1274017633151

The thread has been interrupted

The thread is interrupted : false

Current time millis : 1274017634151

You can see that after one second, the second thread is interrupted and that the interrupted status
has been set to false. If you are not sleeping, but making a lot of heavy actions, you can test for
interrupt like that to make your thread correctly interrupts :

public class InterruptableRunnable implements Runnable {


@Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
//Heavy operation
}
}
}

Now that you know how to interrupt a thread, you can imagine, that simply catch the
InterruptedException is not enough to make your thread "interrupt safe". Imagine that your
thread something like that :

public class UglyRunnable implements Runnable {


@Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
//Heavy operation
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Other operation
}
}
}

And now, an other thread want to interrupt your thread while your thread is sleeping. The sleep
will be interrupted, but the interrupted status will be cleared so the loop will continue. A solution
to make a better thread is to interrupt again the thread after an InterruptedException :

public class BetterRunnable implements Runnable {


@Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
//Heavy operation
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
//Other operation
}
}
}

With that code, the interrupted status will be restored and the loop will be stopped after interrupt.
Depending on your code, you can also add a continue statement after the interrupt() to not make
operations after interrupt. In some cases, you'll also needs to make several if statements to test
the interrupted status to do or not to do some operations.

Java Concurrency Part 3 : Synchronization


with intrinsic locks
create threads and manipulate them, it's time to go to most important things : synchronization.

Synchronization is a way to make some code thread safe. A code that can be accessed by
multiple threads must be made thread safe. Thread Safe describe some code that can be called
from multiple threads without corrupting the state of the object or simply doing the thing the
code must do in right order.

For example, we can take this little class :

public class Example {


private int value = 0;

public int getNextValue(){


return value++;
}
}

It's really simple and works well with one thread, but absolutely not with multiple threads. An
increment like this is not a simple action, but three actions :

Read the current value of "value"


Add one to the current value
Write that new value to "value"

Normally, if you have two threads invoking the getNextValue(), you can think that the first will
get 1 and the next will get 2, but it is possible that the two threads get the value 1. Imagine this
situation :

Thread 1 : read the value, get 0, add 1, so value = 1


Thread 2 : read the value, get 0, add 1, so value = 1
Thread 1 : write 1 to the field value and return 1
Thread 2 : write 1 to the field value and return 1

These situations come from what we call interleaving. Interleaving describe the possible
situations of several threads executing some statements. Only for three operations and two
threads, there is a lot of possible interleavings.

So we must made the operations atomic to works with multiple threads. In Java, the first way to
make that is to use a lock. All Java objects contains an intrinsic locks, we'll use that lock to make
methods or statement atomic. When a thread has a lock, no other thread can acquire it and must
wait for the first thread to release the lock. To acquire the lock, you have to use the synchronized
keyword to automatically acquire and release a lock for a code. You can add the synchronized
keyword to a method to acquire the lock before invoking the method and release it after the
method execution. You can refactor the getNextValue() method using the synchronized keyword
:

public class Example {


private int value = 0;

public synchronized int getNextValue(){


return value++;
}
}

With that, you have the guarantee that only thread can execute the method at the same time. The
used lock is the intrinsic lock of the instance. If the method is static, the used lock is the Class
object of Example. If you have two methods with the synchronized keyword, only one method of
the two will be executed at the same time because the same lock is used for the two methods.
You can also write it using a synchronized block :

public class Example {


private int value = 0;

public int getNextValue() {


synchronized (this) {
return value++;
}
}
}

This is exactly the same as using the synchronized keyword on the method signature. Using
synchronized blocks, you can choose the lock to block on. By example, if you don't want to use
the intrinsic lock of the current object but an other object, you can use an other object just as a
lock :

public class Example {


private int value = 0;

private final Object lock = new Object();

public int getNextValue() {


synchronized (lock) {
return value++;
}
}
}

The result is the same but has one difference, the lock is internal to the object so no other code
can use the lock. With complex classes, it not rare to use several locks to provide thread safety
on the class.

There is an other issue with multiple threads : the visibility of the variables. This seems when a
change made by a thread is visible by an other thread. For performance improvements, the Java
compiler and virtual machines can made some improvements using registers and cache. By
default, you have no guarantee that a change made by a thread is visible to an other thread. To
make a change visible to an other thread, you must use synchronized blocks to ensure visibility
of the change. You must use synchronized blocks for the read and for the write of the shared
values. You must make that for every read/write of a value shared between multiple threads.

You can also use the volatile keyword on the field to ensure the visibility of read/write between
multiple threads. The volatile keyword ensure only visibility, not atomicity. The synchronized
blocks ensure visibility and atomicity. So you can use the volatile keyword on fields that doesn't
need atomicity (if you make only read and write to the field without depending on the current
value of the field by example).

You can also note that this simple example can be solved using AtomicInteger, but that will be
covered later in an other part of the posts.

Pay attention that trying to solve thread safety on a problem can add new issues of deadlock. By
example, if thread A owns the lock 1 and are waiting for the lock 2 and if lock 2 is acquired by
thread B who waits on lock 1, there is a deadlock. Your program is dead. So you have to pay
great attention to the locks.

There is several rules that we must keep in mind when using locks :

1. Every mutable fields shared between multiple threads must be guarded with a lock or
made volatile, if you only need visibility
2. Synchronize only the operations that must synchronized, this improve the performances.
But don't synchronize too few operations. Try to keep the lock only for short operations.
3. Always know which locks are acquired and when there are acquired and by which thread
4. An immutable object is always thread safe

Here we are, I hope that this post helps you to understand thread safety and how to achieve it
using intrinsic locks. In the next posts, we'll see another synchronization methods.

Java Concurrency - Part 4 : Semaphores


We continue in Java Concurrency with the semaphores. Semaphores is also a way to synchronize
threads.

Semaphores are a really simple concept, invented by the famous Dutch computer scientist Edsger
Dijkstra. Basically a semaphore is a counter (integer) that allows a thread to get into a critical
region if the value of the counter is greater than 0. If it's the case, the counter is decremented by
one otherwise, the thread is waiting until it can go. And when the thread go away from the
critical region, the counter is incremented by one to allow one more thread to pass the critical
region. A semaphore is created with a certain value for its counter. So, you can execute two
actions on a semaphore P and V.

By example, if you have a critical that cannot be executed concurrently, you can use a
semaphore:

sem mutex = new sem(1)


P(mutex)
//Critical region
V(mutex)

So you must always call by yourself the P operation before the critical region and V after it. We
call a mutex (mutual exclusion) a semaphore with a value of one. So only one thread can enter
the region guarded by the semaphore. This is the most used semaphore. The other use of
semaphore is to guard a set of resources like database connections or a data pool.

In Java, a semaphore is created using the java.util.concurrent.Semaphore class. You can create
easily :

Semaphore mutex = new Semaphore(1);


Semaphore available = new Semaphore(100);

The P and V operations are represented using the acquire and release methods. The method
acquire can be interrupted if the thread is interrupted. There is an uninterruptible version with the
method acquireUninterruptibly(). There is also a third version with the tryAcquire method. This
method acquire a permit only if there is one permit available, otherwise, this method return false
directly. All the waiting methods have also an overloaded version with a timeout. You can also
acquire several permits at once using the permits argument to the different versions of acquire
methods.

A little example with a mutex using the same example as the previous post on Java concurrency :

public class Example {


private int value = 0;

private final Semaphore mutex = new Semaphore(1)

public int getNextValue() throws InterruptedException {


try {
mutex.acquire();
return value++;
} finally {
mutex.release();
}
}
}

For more informations about Semaphore in Java, the best is to consult the Javadoc of the
Semaphore class.

To conclude, semaphores are a powerful ways to solve concurrency problems, but this is not
adapted to all problems. If you need only mutual exclusion, synchronized blocks are a better
solutions. The problems with semaphores is that you can forget to call the release method and
that can cause deadlock sometimes difficult to find.

Java Concurrency - Part 5 : Monitors (Locks


and Conditions)
After seeing how to synchronize code using semaphores, we'll see how to do that using
monitors.

Monitors are an other mechanism of concurrent programming. It's a higher level mechanism than
semaphores and also more powerful. A monitor is an instance of a class that can be used safely
by several threads. All the methods of a monitor are executed with mutual exclusion. So at most
one thread can execute a method of the monitor at the same time. This mutual exclusion policy
makes easier to work with monitor and to develop the method content of the monitor.

Monitors have an other feature, the possibility to make a thread waiting for a condition. During
the wait time, the thread temporarily gives up its exclusive access and must reacquire it after the
condition has been met. You can also signal one or more threads that a condition has been met.

There is several advantages on using monitors instead of a lower-level mechanisms :

All the synchronization code is centralized in one location and the users of this code
dont need to know how its implemented.
The code doesn't depend on the number of processes, it works for as many processes as
you want
You dont need to release something like a mutex, so you cannot forget to do it

When we must describe a monitor, we simple use the monitor keyword and describe the
methods as common methods :

monitor SimpleMonitor {
public method void testA(){
//Some code
}
public method int testB(){
return 1;
}
}

To describe a condition variable, we use the cond keyword. A condition variable is a kind of
queue of process who are waiting on the same condition. You have several operations available
on a condition, the most important is to signal a process waiting to be awaken and to wait on a
condition. There are some similarities between signal/wait operations and P and V of
semaphores, but this is a little different. The signal operation does nothing if the queue is empty
and the wait operation put always the thread in the waiting queue. The process queue is served in
a first come, first served mode. When a thread wakes up after waiting on a condition, it must
reacquire the lock before continuing in the code.

Before going further, we must have more information about the signal operations. When writing
monitors, you normally have the choice between several philosophies for the signaling operation
:

1. Signal & Continue (SC) : The process who signal keep the mutual exclusion and the
signaled will be awaken but need to acquire the mutual exclusion before going.
2. Signal & Wait (SW) : The signaler is blocked and must wait for mutual exclusion to
continue and the signaled thread is directly awaken and can start continue its operations.
3. Signal & Urgent Wait (SU) : Like SW but the signaler thread has the guarantee than it
would go just after the signaled thread
4. Signal & Exit (SX) : The signaler exits from the method directly after the signal and the
signaled thread can start directly. This philosophy is not often used.

The available policies depends on the programming language, in Java, there is only one policy
available, the SC one.

In Java there is no keyword to directly create a monitor. To implement a monitor, you must
create a new class and use Lock and Condition classes. Lock is the interface is ReentrantLock
is the main used implementation, this is the one that we'll learn to use in the current post. To
create a ReentrantLock, you have two constructors, a default constructor and a constructor with a
boolean argument indicating if the lock is fair or not. A fair lock indicates that the threads will
acquire the locks in the order they ask for. Fairness is a little heavier than default locking
strategies, so use it only if you need it. To acquire the lock, you just have to use the method lock
and unlock to release it.

The explicit locks have the same memory semantics than the synchronized blocks. So the
visibility of the changes is guarantee when you use lock()/unlock() blocks.

So to implement, the monitor example we've seen before, we just need to create a class and use
the lock to make the mutual exclusion :

public class SimpleMonitor {


private final Lock lock = new ReentrantLock();
public void testA() {
lock.lock();

try {
//Some code
} finally {
lock.unlock();
}
}

public int testB() {


lock.lock();

try {
return 1;
} finally {
lock.unlock();
}
}
}

The person who've already read the other parts of this post set will say that it will be easier to use
the synchronized keyword on the two methods. But with synchronized, we will not have the
condition variables. If you don't need condition variables but only locking, it will be easier to use
the synchronized blocks instead of Locks.

You can create conditions using the newCondition method on the lock. A condition is a variable
of type Condition. You can make the current thread wait on the condition using the await
method (and its variant with timeout) and you can signal threads using signal and signalAll
methods. The signalAll methods wakes up all the threads waiting on the condition variable.

Let's try with a simple common example : A bounded buffer. It's a cyclic buffer with a certain
capacity with a start and an end.

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BoundedBuffer {


private final String[] buffer;
private final int capacity;

private int front;


private int rear;
private int count;

private final Lock lock = new ReentrantLock();

private final Condition notFull = lock.newCondition();


private final Condition notEmpty = lock.newCondition();

public BoundedBuffer(int capacity) {


super();
this.capacity = capacity;

buffer = new String[capacity];


}

public void deposit(String data) throws InterruptedException {


lock.lock();

try {
while (count == capacity) {
notFull.await();
}

buffer[rear] = data;
rear = (rear + 1) % capacity;
count++;

notEmpty.signal();
} finally {
lock.unlock();
}
}

public String fetch() throws InterruptedException {


lock.lock();

try {
while (count == 0) {
notEmpty.await();
}

String result = buffer[front];


front = (front + 1) % capacity;
count--;

notFull.signal();

return result;
} finally {
lock.unlock();
}
}
}

So some explications :

1. The two methods are protected with the lock to ensure mutual exclusion
2. Then we use two conditions variables. One to wait for the buffer to be not empty and an
other one to wait for the buffer to be not full.
3. You can see that I have wrapped the await operation on a while loop. This is to avoid
signal stealers problem that can occurs when using Signal & Continue

And that BoundedBuffer can be easily used with several threads with no problems.
As you can see, you can use monitors to solve a lot of concurrent programming problems and
this mechanism is really powerful and performing.

I hope you found that article interesting and that this set of posts about Java concurrency brings
you some stuff about Java.

Java Concurrency - Part 6 : Atomic Variables


When a data (typically a variable) can be accessed by several threads, you must synchronize the
access to the data to ensure visibility and correctness.

By example, if you have a simple counter (yes, once again) :

public class Counter {


private int value;

public int getValue(){


return value;
}

public int getNextValue(){


return value++;
}

public int getPreviousValue(){


return value--;
}
}

This class works really well in single-threaded environment, but don't work at all when several
threads access the same Counter instance. If you don't know why, read this post about
synchronization. You can solve the problem using synchronized at method level :

public class SynchronizedCounter {


private int value;

public synchronized int getValue(){


return value;
}

public synchronized int getNextValue(){


return value++;
}

public synchronized int getPreviousValue(){


return value--;
}
}

This class now works well. But locking is not a lightweight mechanism and have several
disadvantages. When several threads try to acquire the same lock, one or more threads will be
suspended and they will be resumed later. When the critical section is little, the overhead is
really heavy especially when the lock is often acquired and there is a lot of contention. Another
disadvantage is that the other threads waiting of the lock cannot do something else during
waiting and if the thread who has the lock is delayed (due to a page fault or the end of the time
quanta by example), the others threads cannot take their turn.

So how to do to avoid this disadvantages ? We must use non-blocking algorithms. This


algorithms don't use blocking mechanisms and by that fact are more scalable and performing.
These algorithms use low-level machine instructions which are atomic to ensure the atomicity of
higher-level operations. While locking is a pessimistic approach, we can also use optimistic
technique to develop algorithms. This time, we'll detect collisions between threads in which case,
the operation fails and we do something else (often retrying the same operation).

The actual processors provide several instructions that simplify greatly the implementation of
these non-blocking algorithms, the most-used operation today is the compare-and-swap
operation (CAS). This operation takes three parameters, the memory address, the expected
current value and the new value. It atomically update the value at the given memory address if
the current value is the expected, otherwise it do nothing. In both cases, the operation return the
value at the address after the operation execution. So when several threads try to execute the
CAS operation, one thread wins and the others do nothing. So the caller can choose to retry or to
do something else. We often use this operation to implement another operation, the compare-
and-set. This method makes exactly the same things as CAS but return a boolean indicating if the
operation succeeded or not.

Before Java 5.0, this operation was not available directly to developer, but in Java 5.0 several
atomic variables (for int, long, boolean and reference values) were added. The int and long
versions also supports numeric operations. The JVM compiles these classes with the better
operations provided by the hardware machine, CAS or a Java implementation of the operation
using a lock. Here are the classes :

AtomicInteger
AtomicLong
AtomicBoolean
AtomicReference

All these classes supports compare-and-set (via the compareAndSet() method) and other
operations (get(), set() and getAndSet()). The setters operations are implemented using
compareAndSet. These classes supports multi-threaded access and have a better scalability than
synchronizing all the operations.

Here is how we can rewrite our counter using an AtomicInteger :

public class AtomicCounter {


private final AtomicInteger value = new AtomicInteger(0);

public int getValue(){


return value.get();
}

public int getNextValue(){


return value.incrementAndGet();
}

public int getPreviousValue(){


return value.decrementAndGet();
}
}

The incrementAndGet() and decrementAndGet() methods are two of the numeric operations
provided by the AtomicLong and AtomicInteger classes. You also have getAndDecrement(),
getAndIncrement(), getAndAdd(int i) and addAndGet().

This version is faster than the synchronized one and is also thread safe.

If you only have the compareAndSet(), here is how we can implement increment() method using
it :

public void increment(AtomicInteger integer){


while(true){
int current = integer.get();
int next = current + 1;

if(integer.compareAndSet(current, next)){
return;
}
}
}

This seems to be complicated, but this is the cost of non-blocking algorithms. When we detect
collision, we retry until the operation succeeded. This is the common schema for non-blocking
algorithms.

Here is a thread-safe Stack implemented using AtomicReference :

public class Stack {


private final AtomicReference<Element> head = new
AtomicReference<Element>(null);

public void push(String value){


Element newElement = new Element(value);

while(true){
Element oldHead = head.get();
newElement.next = oldHead;

//Trying to set the new element as the head


if(head.compareAndSet(oldHead, newElement)){
return;
}
}
}

public String pop(){


while(true){
Element oldHead = head.get();

//The stack is empty


if(oldHead == null){
return null;
}

Element newHead = oldHead.next;

//Trying to set the new element as the head


if(head.compareAndSet(oldHead, newHead)){
return oldHead.value;
}
}
}

private static final class Element {


private final String value;
private Element next;

private Element(String value) {


this.value = value;
}
}
}

It's really more complicated than using synchronized on the two methods but also more
performing if there is contention (and often even if there is no contention).

So this ends this post. To conclude, atomic variables classes are a really good way to implement
non-blocking algorithms and moreover are also a very good alternative to volatile variables,
because they can provide atomicity and visibility.

Java Concurrency - Part 7 : Executors and


thread pools
Let's start with a new post in the Java concurrency series.

This time we'll learn how to start cleanly new threads and to manage thread pools. In Java, if you
have a Runnable like this :

Runnable runnable = new Runnable(){


public void run(){
System.out.println("Run");
}
}
You can easily run it in a new thread :

new Thread(runnable).start();

This is very simple and clean, but what if you've several long running tasks that you want to load
in parralel and then wait for the completion of all the tasks, it's a little bit harder to code and if
you want to get the return value of all the tasks it becomes really difficult to keep a good code.
But like for almost any problems, Java has a solution for you, the Executors. This simple class
allows you to create thread pools and thread factories.

A thread pool is represented by an instance of the class ExecutorService. With an


ExecutorService, you can submit task that will be completed in the future. Here are the type of
thread pools you can create with the Executors class :

Single Thread Executor : A thread pool with only one thread. So all the submitted task
will be executed sequentially. Method : Executors.newSingleThreadExecutor()
Cached Thread Pool : A thread pool that create as many threads it needs to execute the
task in parralel. The old available threads will be reused for the new tasks. If a thread is
not used during 60 seconds, it will be terminated and removed from the pool. Method :
Executors.newCachedThreadPool()
Fixed Thread Pool : A thread pool with a fixed number of threads. If a thread is not
available for the task, the task is put in queue waiting for an other task to ends. Method :
Executors.newFixedThreadPool()
Scheduled Thread Pool : A thread pool made to schedule future task. Method :
Executors.newScheduledThreadPool()
Single Thread Scheduled Pool : A thread pool with only one thread to schedule future
task. Method : Executors.newSingleThreadScheduledExecutor()

Once you have a thread pool, you can submit task to it using the different submit methods. You
can submit a Runnable or a Callableto the thread pool. The method return a Future representing
the future state of the task. If you submitted a Runnable, the Future object return null once the
task finished.

By example, if you have this Callable :

private final class StringTask implements Callable<String> {


public String call(){
//Long operations

return "Run";
}
}

If you want to execute that task 10 times using 4 threads, you can use that code :

ExecutorService pool = Executors.newFixedThreadPool(4);

for(int i = 0; i < 10; i++){


pool.submit(new StringTask());
}

But you must shutdown the thread pool in order to terminate all the threads of the pool :

pool.shutdown();

If you don't do that, the JVM risk to not shutdown because there is still threads not terminated.
You can also force the shutdown of the pool using shutdownNow, with that the currently running
tasks will be interrupted and the tasks not started will not be started at all.

But with that example, you cannot get the result of the task. So let's get the Future objects of the
tasks :

ExecutorService pool = Executors.newFixedThreadPool(4);

List<Future<String>> futures = new ArrayList<Future<String>>(10);

for(int i = 0; i < 10; i++){


futures.add(pool.submit(new StringTask()));
}

for(Future<String> future : futures){


String result = future.get();

//Compute the result


}

pool.shutdown();

But this code is a bit complicated. And there is a disadvantage. If the first task takes a long time
to compute and all the other tasks ends before the first, the current thread cannot compute the
result before the first task ends. Once again, Java has the solution for you, CompletionService.

A CompletionService is a service that make easier to wait for result of submitted task to an
executor. The implementation is ExecutorCompletionService who's based on an ExecutorService
to work. So let's try :

ExecutorService threadPool = Executors.newFixedThreadPool(4);

CompletionService<String> pool = new


ExecutorCompletionService<String>(threadPool);

for(int i = 0; i < 10; i++){


pool.submit(new StringTask());
}

for(int i = 0; i < 10; i++){


String result = pool.take().get();

//Compute the result


}
threadPool.shutdown();

With that, you have the result in the order they are completed and you don't have to keep a
collection of Future.

Here we are, you have the tools in hand to launch tasks in parralel using performing thread pools.
Using Executors, ExecutorService and CompletionService you can create complex algorithm
using several taks. With that tools, it's really easy to change the number of threads performing in
parralel or adding more tasks without changing a lot of code.

Java 7 : More concurrency


With Java 7 (Dolphin), we'll have some concurrency and collections updates with the
JSR166y, extension of the JSR166 of Doug Lea.

In this post, we'll see the most important news :

Fork/Join Framework
TrasnferQueue
ThreadLocalRandom

Fork/Join Framework

The most important improvement is a new Fork/Join Framework. Fork/Join is basically the
parralel version of the divide-and-conquer algorithm resolution. Here is the typical form of that
problems (taken from Doug Lea) :

Result solve(Problem problem) {


if (problem is small)
directly solve problem
else {
split problem into independent parts
fork new subtasks to solve each part
join all subtasks
compose result from subresults
}
}

Java 7 provide a new class ForkJoinPool to run ForkJoinTask. A ForkJoinTask is lighter than
a thread. If you have a lot of ForkJoinTask, you can host them with a smallest number of threads.
Two implementations of ForkJoinTask are provided :

RecursiveAction : A recursive resultless ForkJoinTask


RecursiveTask : A recursive ForkJoinTask that return an object of type E
Of course, you can also directly use the ForkJoinTask class but the recursive actions are enough
in almost all the cases.

From a ForkJoinTask you can invoke other task (fork them) using invokeAll methods.

So, now that we have covered the main concepts of this framework, we could start with a little
example (directly taken from Javadoc build 87). We'll use divide and conquer to increment all
the elements of an array. To know if the problem is small enough to solve it directly, we'll use a
threshold representing the number of elements that we can increment directly. If we have more
elements than the threshold, we will fork in two task otherwise, we'll compute directly the
incrementation on the array. So here is our task :

public class IncrementTask extends RecursiveAction {


private final long[] array;
private final int low;
private final int high;

private static final int THRESHOLD = 5000;

public IncrementTask(long[] array, int low, int high) {


super();

this.array = array;
this.low = low;
this.high= high;
}

@Override
protected void compute() {
if (high - low < THRESHOLD) {
for (int i = low; i < high; ++i){
array[i]++;
}
} else {
int mid = (low + high) >>> 1;

invokeAll(new IncrementTask(array, low, mid), new


IncrementTask(array, mid, high));
}
}
}

And you can launch that on an array using ForkJoinPool :

RecursiveAction mainTask = new IncrementTask (anArray, 0, anArray.length);


ForkJoinPool mainPool = new ForkJoinPool();
mainPool.invoke(mainTask

All the elements of the array will be incremented. Depending on the size of the array and of the
threshold, the problem will be divided in several sub problems and all these task will be managed
by the ForkJoinPool.
You can also make action that return something. By example, we can compute the sum of all the
elements of an array :

public class SumTask extends RecursiveTask {


private final long[] array;
private final int low;
private final int high;

private static final int THRESHOLD = 5000;

public SumTask(long[] array, int low, int high) {


super();

this.array = array;
this.low = low;
this.high= high;
}

@Override
protected Long compute() {
if (high - low < THRESHOLD) {
long sum = 0;

for (int i = low; i < high; ++i){


sum += array[i];
}

return sum;
} else {
int mid = (low + high) >>> 1;

RecursiveTask left = new SumTask(array, low, mid);


RecursiveTask right = new SumTask(array, mid, high);

right.fork();

return left.compute() + right.join();


}
}
}

And you can use it like that :

RecursiveTask sumTask = new SumTask(anArray, 0, anArray.length);


ForkJoinPool mainPool = new ForkJoinPool();
Long sum = mainPool.invoke(sumTask);

I think it's a clean way to solve big problems with divide-and-conquer.

You can also imagine others ways to divide the problems. An example is to compute the
THRESOLD left elements in the task and create a new task to compute the right elements. With
that, we create less tasks, but it depends on the context and on the problems. In practive, you'll
have normally more complex problems but if you can find a way to divide the problems, you
can use that new framework and have a very clean code.
TransferQueue

A new interesting collection. This collection is a blocking queue especially made for
producers/consumers. With that kind of queue, the producers can await for receipt of by the
consumers with a new transfer(E) method or like normal queue without waiting for receipt with
the put(E) method. It's also possible to make a transfer with timeout with the tryTransfer method.
There is no change in the consumer part, you always use take() to get an element and waiting for
an element. You've also access to the number of waiting consumer with the
getWaitingConsumerCount().

The implementation to use is the LinkedTransferQueue based on linked nodes. The elements
are ordered with FIFO. Here are some methods you can use with that new collection :

TransferQueue<String> transfer = new LinkedTransferQueue<String>();

transfer.transfer("Hello"); //Wait for a consumer

if(transfer.tryTransfer("World")){//Don't wait for a consumer


//The element has been transfered to a consumer
} else {
//There were no waiting consumer. The element has not been enqueued.
}

boolean transfered = transfer.tryTransfer("Goodbye", 5, TimeUnit.SECONDS);

while(transfer.hasWaitingConsumer()){
//There is at least one consumer waiting for a transfer
}

It's also an interesting stuff. Useful by example in the case of message passing.

ThreadLocalRandom

A really simple but useful enhancement is the add of the ThreadLocalRandom class. This class
is a random number generator linked to the current Thread. It seems that if you use this
generator from two different thread, you will have two different random generators. The
generator is initialized with a generated seed that you cannot modify (setSeed() throws an
UnsupportedOperationException).

You can use that class like that :

long l = ThreadLocalRandom.current().nextLong(22L);

If you always use this form, you have the guarantee that the random generator will never be
shared between two threads. Moreover, this new class provide methods to generate a bounded
numbers. By example, to generate a pseudo-random number between 10, inclusive and 33,
exclusive, you can type :

int i = ThreadLocalRandom.current().nextInt(10, 33);


This is a little improvement but really useful, i think.

So here we are. I've covered the main features added on Java 7 for concurrency. I hope you find
that stuff interesting and that discovering this features will help you to make concurrent
programming in Java 7.

You might also like