
Tuesday, January 26, 2016
Atomic operations
Atomic operations are performed in a single unit of task without interference from other operations.
Atomic operations are necessity in multi-threaded environment to avoid data inconsistency.


The Java language specification guarantees that reading or writing a variable is an atomic operation(unless the variable is of type long or double). Operations variables of type long or double are only atomic if they declared with the volatile keyword. .
Assume i is defined as int. The i++ (increment) operation it not an atomic operation in Java. This also applies for the other numeric types, e.g. long. etc).
The i++ operation first reads the value which is currently stored in i (atomic operations) and then it adds one to it (atomic operation). But between the read and the write the value of i might have changed.
Since Java 1.5 the java language provides atomic variables,
e.g. AtomicInteger or AtomicLong which provide methods like getAndDecrement(), getAndIncrement() and getAndSet() which are atomic.
Example without Atomic,
Let’s create a simple multi-threaded program where every thread increments the shared count variable 4 times. So if there are two threads, after they finish count value should be 8.
public class JavaAtomic {
public static void main(String[] args) throws InterruptedException {
ProcessingThread pt = new ProcessingThread();
Thread t1 = new Thread(pt, "t1");
t1.start();
Thread t2 = new Thread(pt, "t2");
t2.start();
t1.join();
t2.join();
System.out.println("Processing count=" + pt.getCount());
}
}
class ProcessingThread implements Runnable {
private int count;
@Override
public void run() {
for (int i = 1; i < 5; i++) {
processSomething(i);
count++;
}
}
public int getCount() {
return this.count;
}
private void processSomething(int i) {
// processing some job
try {
Thread.sleep(i * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
If you will run above program, you will notice that count value varies between 5,6,7,8. The reason is because count++ is not an atomic operation. So by the time one threads read it’s value and increment it by one, other thread has read the older value leading to wrong result.
Example with Atomic operation,
import java.util.concurrent.atomic.AtomicInteger;
public class JavaAtomic {
public static void main(String[] args) throws InterruptedException {
ProcessingThread pt = new ProcessingThread();
Thread t1 = new Thread(pt, "t1");
t1.start();
Thread t2 = new Thread(pt, "t2");
t2.start();
t1.join();
t2.join();
System.out.println("Processing count=" + pt.getCount());
}
}
class ProcessingThread implements Runnable {
private AtomicInteger count = new AtomicInteger();
@Override
public void run() {
for (int i = 1; i < 5; i++) {
processSomething(i);
count.incrementAndGet();
}
}
public int getCount() {
return this.count.get();
}
private void processSomething(int i) {
// processing some job
try {
Thread.sleep(i * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Benefits of using Atomic Concurrency classes is that we don’t need to worry about synchronization at each and every place.
We are dealing with integers and it’s assumed to be more efficient that synchronization which involves locking resources.
Read / Write locks
Imagine you have an application that reads and writes some resource, but writing it is not done as much as reading it is.
Two threads reading the same resource does not cause problems for each other, so multiple threads that want to read the resource are granted access at the same time, overlapping. But, if a single thread wants to write to the resource, no other reads nor writes must be in progress at the same time.
To solve this problem of allowing multiple readers but only one writer, you will need a read / write lock.
Java 5 comes with read / write lock implementations in the
java.util.concurrent
package. Even so, it may still be useful to know the theory behind their implementation.Read / Write Lock Java Implementation
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ThreadSafeArrayList<E>
{
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private final Lock readLock = readWriteLock.readLock();
private final Lock writeLock = readWriteLock.writeLock();
private final List<E> list = new ArrayList<>();
public void set(E o)
{
writeLock.lock();
try
{
list.add(o);
System.out.println("Adding element by thread"+Thread.currentThread().getName());
}
finally
{
writeLock.unlock();
}
}
public E get(int i)
{
readLock.lock();
try
{
System.out.println("Printing elements by thread"+Thread.currentThread().getName());
return list.get(i);
}
finally
{
readLock.unlock();
}
}
public static void main(String[] args)
{
ThreadSafeArrayList<String> threadSafeArrayList = new ThreadSafeArrayList<>();
threadSafeArrayList.set("1");
threadSafeArrayList.set("2");
threadSafeArrayList.set("3");
System.out.println("Printing the First Element : "+threadSafeArrayList.get(1));
}
}
OUTPUT :
Adding element by threadmain
Adding element by threadmain
Adding element by threadmain
Printing elements by threadmain
Reading from List : 2
Live Scenario,
In the great majority of database applications, the frequency of read operations greatly exceeds the frequency of write operations. This is why databases implement read-write locks for their records, which allow for concurrent reading, but still demand exclusive writing. This can markedly increase performance.
Occasionally, a class may benefit as well from a read-write lock, for exactly the same reasons - reads are much more frequent than writes. As usual, you should measure performance to determine if a read-write lock is really improving performance.
Here's a sketch of how to use such locks. It uses the ReentrantReadWriteLock of the java.util.concurrent package.
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
User preferences, using a read-write lock.
<P>The context: preference information is read in upon startup.
The config data is 'read-mostly': usually, a caller simply reads the
information. It gets updated only occasionally.
<P>Using a read-write lock means that multiple readers can access the
same data simultaneously. If a single writer gets the lock, however, then
all other callers (either reader or writer) will block until the lock is
released by the writer.
<P>(In practice, Brian Goetz reports that the implementation of ConcurrentHashMap
is so good that it would likely suffice in many cases, instead of a read-write lock.)
*/
public final class Preferences {
/** Fetch a setting - this is the more common operation. */
public String fetch(String aName){
String result = "";
fReadLock.lock();
try {
result = fPreferences.get(aName);
}
finally {
fReadLock.unlock();
}
return result;
}
/** Change a setting - this is the less common operation. */
public void update(String aName, String aValue){
fWriteLock.lock();
try {
fPreferences.put(aName, aValue);
}
finally {
fWriteLock.unlock();
}
}
//...elided
// PRIVATE
/** Holds the preferences as simple name-value pairs of Strings. */
private final Map<String, String> fPreferences = new LinkedHashMap<>();
private final ReentrantReadWriteLock fLock = new ReentrantReadWriteLock();
private final Lock fReadLock = fLock.readLock();
private final Lock fWriteLock = fLock.writeLock();
}
Locks
A Simple Lock
Let's start out by looking at a synchronized block of Java code:
public class Counter{ private int count = 0; public int inc(){ synchronized(this){ return ++count; } } }
Notice the
synchronized(this)
block in the inc()
method. This block makes sure that only one thread can execute the return ++count
at a time. The code in the synchronized block could have been more advanced, but the simple ++count
suffices to get the point across.
The
Counter
class could have been written like this instead, using a Lock
instead of a
synchronized block:
public class Counter{ private Lock lock = new Lock(); private int count = 0; public int inc(){ lock.lock(); int newCount = ++count; lock.unlock(); return newCount; } }
The
lock()
method locks the Lock
instance so that all threads calling lock()
are blocked until unlock()
is executed.
Here is a simple
Lock
implementation:public class Lock{ private boolean isLocked = false; public synchronized void lock() throws InterruptedException{ while(isLocked){ wait(); } isLocked = true; } public synchronized void unlock(){ isLocked = false; notify(); } }
Notice the
while(isLocked)
loop, which is also called a "spin lock"Synchronization
Why Synchronization ?
- Deadlock on shared resources
- Loss of update
- Waiting on each other
Synchronization options
- Synchronization method
- Synchronization block
- locks
- Concurrency package implementations
Synchronization method flow,

Synchronization Method level and block level,

Example
Java synchronized method
If you declare any method as synchronized, it is known as synchronized method.
Synchronized method is used to lock an object for any shared resource.
When a thread invokes a synchronized method, it automatically acquires the lock for that object and releases it when the thread completes its task.
//example of java synchronized method
class Table{
synchronized void printTable(int n){//synchronized method
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
public class TestSynchronization2{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Output:
5
10
15
20
25
100
200
300
400
500

Synchronization Method level and block level,

Example
Java synchronized method
If you declare any method as synchronized, it is known as synchronized method.
Synchronized method is used to lock an object for any shared resource.
When a thread invokes a synchronized method, it automatically acquires the lock for that object and releases it when the thread completes its task.
//example of java synchronized method
class Table{
synchronized void printTable(int n){//synchronized method
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
public class TestSynchronization2{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Output:
5
10
15
20
25
100
200
300
400
500
Thread Joins
The join() method:
The join() method waits for a thread to die.
In other words, it causes the currently running threads to stop executing until the thread it joins with completes its task.
Syntax:
public void join()throws InterruptedException
public void join(long milliseconds)throws InterruptedException
Example of join() method
class TestJoinMethod1 extends Thread{
public void run(){
for(int i=1;i<=5;i++){
try{
Thread.sleep(500);
}catch(Exception e){System.out.println(e);}
System.out.println(i);
}
}
public static void main(String args[]){
TestJoinMethod1 t1=new TestJoinMethod1();
TestJoinMethod1 t2=new TestJoinMethod1();
TestJoinMethod1 t3=new TestJoinMethod1();
t1.start();
try{
t1.join();
}catch(Exception e){System.out.println(e);}
t2.start();
t3.start();
}
}
Output:1
2
3
4
5
1
1
2
2
3
3
4
4
5
5
As you can see in the above example,when t1 completes its task then t2 and t3 starts executing.
Example of join(long miliseconds) method
class TestJoinMethod2 extends Thread{
public void run(){
for(int i=1;i<=5;i++){
try{
Thread.sleep(500);
}catch(Exception e){System.out.println(e);}
System.out.println(i);
}
}
public static void main(String args[]){
TestJoinMethod2 t1=new TestJoinMethod2();
TestJoinMethod2 t2=new TestJoinMethod2();
TestJoinMethod2 t3=new TestJoinMethod2();
t1.start();
try{
t1.join(1500);
}catch(Exception e){System.out.println(e);}
t2.start();
t3.start();
}
}
Output:1
2
3
1
4
1
2
5
2
3
3
4
4
5
5
In the above example,when t1 is completes its task for 1500 miliseconds(3 times) then t2 and t3 starts executing.
getName(),setName(String) and getId() method:
public String getName()
public void setName(String name)
public long getId()
class TestJoinMethod3 extends Thread{
public void run(){
System.out.println("running...");
}
public static void main(String args[]){
TestJoinMethod3 t1=new TestJoinMethod3();
TestJoinMethod3 t2=new TestJoinMethod3();
System.out.println("Name of t1:"+t1.getName());
System.out.println("Name of t2:"+t2.getName());
System.out.println("id of t1:"+t1.getId());
t1.start();
t2.start();
t1.setName("Sonoo Jaiswal");
System.out.println("After changing name of t1:"+t1.getName());
}
}
Output:Name of t1:Thread-0
Name of t2:Thread-1
id of t1:8
running...
After changling name of t1:Sonoo Jaiswal
running...
The currentThread() method:
The currentThread() method returns a reference to the currently executing thread object.
Syntax:
public static Thread currentThread()
Example of currentThread() method
class TestJoinMethod4 extends Thread{
public void run(){
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String args[]){
TestJoinMethod4 t1=new TestJoinMethod4();
TestJoinMethod4 t2=new TestJoinMethod4();
t1.start();
t2.start();
}
}
Output:Thread-0
Thread-1
Thread Groups , Priority and Scheduler
Thread Group
Java provides a convenient way to group multiple threads in a single object. In such way, we can suspend, resume or interrupt group of threads by a single method call.

Example code,
public class ThreadGroupDemo implements Runnable{
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
ThreadGroupDemo runnable = new ThreadGroupDemo();
ThreadGroup tg1 = new ThreadGroup("Parent ThreadGroup");
Thread t1 = new Thread(tg1, runnable,"one");
t1.start();
Thread t2 = new Thread(tg1, runnable,"two");
t2.start();
Thread t3 = new Thread(tg1, runnable,"three");
t3.start();
System.out.println("Thread Group Name: "+tg1.getName());
tg1.list();
}
}
Output:
one
two
three
Thread Group Name: Parent ThreadGroup
java.lang.ThreadGroup[name=Parent ThreadGroup,maxpri=10]
Thread[one,5,Parent ThreadGroup]
Thread[two,5,Parent ThreadGroup]
Thread[three,5,Parent ThreadGroup]
Thread Priorities
public static int MIN_PRIORITY
public static int NORM_PRIORITY
public static int MAX_PRIORITY
Default priority of a thread is 5 (NORM_PRIORITY). The value of MIN_PRIORITY is 1 and the value of MAX_PRIORITY is 10.
Example of priority of a Thread:
class TestMultiPriority1 extends Thread{
public void run(){
System.out.println("running thread name is:"+Thread.currentThread().getName());
System.out.println("running thread priority is:"+Thread.currentThread().getPriority());
}
public static void main(String args[]){
TestMultiPriority1 m1=new TestMultiPriority1();
TestMultiPriority1 m2=new TestMultiPriority1();
m1.setPriority(Thread.MIN_PRIORITY);
m2.setPriority(Thread.MAX_PRIORITY);
m1.start();
m2.start();
}
}
Output:
running thread name is:Thread-0
running thread priority is:10
running thread name is:Thread-1
running thread priority is:1
Thread Scheduler
Thread scheduler in java is the part of the JVM that decides which thread should run.
There is no guarantee that which runnable thread will be chosen to run by the thread scheduler.
Only one thread at a time can run in a single process.
The thread scheduler mainly uses preemptive or time slicing scheduling to schedule the threads.
Difference between preemptive scheduling and time slicing
Under preemptive scheduling, the highest priority task executes until it enters the waiting or dead states or a higher priority task comes into existence.
Under time slicing, a task executes for a predefined slice of time and then reenters the pool of ready tasks.
The scheduler then determines which task should execute next, based on priority and other factors.
Java provides a convenient way to group multiple threads in a single object. In such way, we can suspend, resume or interrupt group of threads by a single method call.

Example code,
public class ThreadGroupDemo implements Runnable{
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
ThreadGroupDemo runnable = new ThreadGroupDemo();
ThreadGroup tg1 = new ThreadGroup("Parent ThreadGroup");
Thread t1 = new Thread(tg1, runnable,"one");
t1.start();
Thread t2 = new Thread(tg1, runnable,"two");
t2.start();
Thread t3 = new Thread(tg1, runnable,"three");
t3.start();
System.out.println("Thread Group Name: "+tg1.getName());
tg1.list();
}
}
Output:
one
two
three
Thread Group Name: Parent ThreadGroup
java.lang.ThreadGroup[name=Parent ThreadGroup,maxpri=10]
Thread[one,5,Parent ThreadGroup]
Thread[two,5,Parent ThreadGroup]
Thread[three,5,Parent ThreadGroup]
Thread Priorities
- Each thread have a priority.
- Priorities are represented by a number between 1 and 10.
- In most cases, thread scheduler schedules the threads according to their priority (known as preemptive scheduling). But it is not guaranteed because it depends on JVM specification that which scheduling it chooses.
public static int MIN_PRIORITY
public static int NORM_PRIORITY
public static int MAX_PRIORITY
Default priority of a thread is 5 (NORM_PRIORITY). The value of MIN_PRIORITY is 1 and the value of MAX_PRIORITY is 10.
Example of priority of a Thread:
class TestMultiPriority1 extends Thread{
public void run(){
System.out.println("running thread name is:"+Thread.currentThread().getName());
System.out.println("running thread priority is:"+Thread.currentThread().getPriority());
}
public static void main(String args[]){
TestMultiPriority1 m1=new TestMultiPriority1();
TestMultiPriority1 m2=new TestMultiPriority1();
m1.setPriority(Thread.MIN_PRIORITY);
m2.setPriority(Thread.MAX_PRIORITY);
m1.start();
m2.start();
}
}
Output:
running thread name is:Thread-0
running thread priority is:10
running thread name is:Thread-1
running thread priority is:1
Thread Scheduler
Thread scheduler in java is the part of the JVM that decides which thread should run.
There is no guarantee that which runnable thread will be chosen to run by the thread scheduler.
Only one thread at a time can run in a single process.
The thread scheduler mainly uses preemptive or time slicing scheduling to schedule the threads.
Difference between preemptive scheduling and time slicing
Under preemptive scheduling, the highest priority task executes until it enters the waiting or dead states or a higher priority task comes into existence.
Under time slicing, a task executes for a predefined slice of time and then reenters the pool of ready tasks.
The scheduler then determines which task should execute next, based on priority and other factors.
Threads
A thread is a lightweight sub process, a smallest unit of processing. It is a separate path of execution.
Threads are independent, if there occurs exception in one thread, it doesn't affect other threads. It shares a common memory area.
Thread is executed inside the process.
Thread life cycle
Ways of creating threads in java

Example 1,
Implements Runnable interface,
class MyThread implements Runnable { public void run() { System.out.println("concurrent thread started running.."); } } class MyThreadDemo { public static void main( String args[] ) { MyThread mt = new MyThread(); Thread t = new Thread(mt); t.start(); } }
Output : concurrent thread started running..
By Extending Thread class,
class MyThread extends Thread { public void run() { System.out.println("Concurrent thread started running.."); } } classMyThreadDemo { public static void main( String args[] ) { MyThread mt = new MyThread(); mt.start(); } }
Output : concurrent thread started running..
Note on creating threads,

Using the
Thread
class directly has the following disadvantages.- Creating a new thread causes some performance overhead
- Too many threads can lead to reduced performance, as the CPU needs to switch between these threads.
- You cannot easily control the number of threads, therefore you may run into out of memory errors due to too many threads.
Multitasking
Multitasking is a process of executing multiple tasks simultaneously. We use multitasking to utilize the CPU. Multitasking can be achieved by two ways:
- Process-based Multitasking(Multiprocessing)
- Thread-based Multitasking(Multi threading)
1) Process-based Multitasking (Multiprocessing)
- Each process have its own address in memory i.e. each process allocates separate memory area.
- Process is heavyweight.
- Cost of communication between the process is high.
- Switching from one process to another require some time for saving and loading registers, memory maps, updating lists etc.
2) Thread-based Multitasking (Multithreading)
- Threads share the same address space.
- Thread is lightweight.
- Cost of communication between the thread is low.
Process vs. threads
A process runs independently and isolated of other processes. It cannot directly access shared data in other processes. The resources of the process, e.g. memory and CPU time, are allocated to it via the operating system.
A thread is a so called lightweight process. It has its own call stack, but can access shared data of other threads in the same process. Every thread has its own memory cache. If a thread reads shared data it stores this data in its own memory cache. A thread can re-read the shared data.
A Java application runs by default in one process. Within a Java application you work with several threads to achieve parallel processing or asynchronous behavior.
Concurrency issues
- Lost of update
- Running behind each other
- Shared access - Dead lock

Subscribe to:
Posts (Atom)