Java Concurrency Kishanthan Thangarajah Senior Software Engineer
Agenda o Why Concurrency? o Processes and Threads o Java Thread Example o Thread Safety o Race Conditions & Critical Sections o Java Synchronization o Deadlock, Starvation o Java Concurrent APIs
Why Concurrency? o Benefits o Make use of multi processor system o Handle asynchronous behaviour (eg : Server) o Better responsive applications (eg : UI)
Why Concurrency? o Risks o Thread safety o Deadlocks, starvation o Performance overhead
Processes and Threads o Process o Runs independently of other processes and has separate memory space. o Thread o Also runs independently of other threads, but can access shared data of other threads in the same process. oA Java application at least has one thread (main)
Java Thread Example o Thread subclass public class ExampleThread extends Thread { @Override public void run() { System.out.println("Hello !!!"); } } ExampleThread thread = new ExampleThread(); thread.start();
Java Thread Example o Implement “Runnable” interface public class ExampleRunnable implements Runnable { @Override public void run() { System.out.println("Hello !!!"); } } Thread thread = new Thread(new ExampleRunnable()); thread.start();
Java Thread Example o Common mistake with threads Calling run() instead of start() This will not start a new thread, instead the run() method will be executed by the same thread.
Java Thread Example o Pausing a thread Thread.sleep(5000); Example : Cluster initialization o Interrupting a thread ExampleThread thread = new ExampleThread(); thread.start(); thread.interrupt();
Java Thread Example othread.join() : wait on another thread for completion The join method allows one thread to wait for the completion of another.
Java Thread Example oThread Local o used with variables that can only be accessed (read and write) by the same thread. public class ExampleThreadLocal { public static class ExampleRunnable implements Runnable { private ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(); @Override public void run() { threadLocal.set((int) (Math.random() * 500)); System.out.println("Thread Local Variable Value : " + threadLocal.get()); } } public static void main(String[] args) { ExampleRunnable runnable = new ExampleRunnable(); Thread t1 = new Thread(runnable); Thread t2 = new Thread(runnable); t1.start(); t2.start(); } }
Java Thread Example oThread Local o Practical example : CarbonContext oThread Signalling o wait(), notify() and notifyAll()
Thread Safety o If multiple threads access (read or write) the same variable (or a code section) without proper synchronization, the application is not thread safe. o Don't share mutable variable between threads or make the variable immutable. o Synchronize the access of the variable.
Race Condition & Critical Sections o If two threads try to compete for same resource and if the order in which the resource is accessed is of interest, then there arise a race condition. oA resource (code section) that leads to race conditions is called a critical section.
Race Condition & Critical Sections public class Example { private int x = 0; public void increment() { x++; } }
Race Condition & Critical Sections o Single expression composed of multiple steps - Thread Interference o Inconsistence view of the value - Memory consistency error
Java Synchronization public class Example { private int x = 0; public synchronized void increment() { x++; } public synchronized int getValue() { return x; } }
Java Synchronization o No two threads can execute synchronized methods on the same object instance. - Locks on objects. o Changes to the object within synchronized section are visible to all threads. - Resumed threads will see the updated value
Java Synchronization o The synchronized keyword can be used with the following: o Instance methods or code segment blocks within instance methods o Static methods or code segment blocks within static methods
Java Synchronization o Synchronized statements public void increment() { synchronized (this) { x++; } }
Java Synchronization o Use of “static” public class Example { public static synchronized void sayHello1() { System.out.println("Hello1 !!!"); } public static void sayHello2() { synchronized (Example.class) { System.out.println("Hello2 !!!"); } } }
Java Synchronization o Reentrant Synchronization A thread can acquire lock already owned by it self. public class Example { public synchronized void sayHello1() { System.out.println("Hello1 !!!"); sayHello2(); } public void sayHello2() { synchronized (this) { System.out.println("Hello2 !!!"); try { Thread.sleep(2000); } catch (InterruptedException e) { System.out.println("I was interrupted !!!"); } } } }
Deadlock & Starvation o Deadlock o Two or more threads are blocked forever, waiting for each other. o Occur when multiple threads need the same locks, at the same time, but obtain them in different order. Thread 1 locks A, waits for B, Thread 2 locks B, waits for A o Practical Example : Issue found with CarbonDeploymentSchedulerTask and ClusterMessage o Starvation o A thread is not given regular access to CPU time (shared resources) because of other threads.
Deadlock & Starvation o Deadlock Prevention o Order how the locks can be acquired o Use locks instead of synchronized statements (fairness)
Java Concurrent APIs o Found under java.util.concurrent o High level concurrency objects o Locks o Executors o Concurrent Collections o Atomic variables
Java Concurrent APIs o Locks Lock lock = …... lock.lock(); try { // critical section } finally { lock.unlock(); }
Java Concurrent APIs o ReentrantLock o Provide reentrant behaviour, same as with synchronized blocks, but with extended features (fairness). public class LockExample { private Lock lock = new ReentrantLock(); private int x = 0; public void increment() { lock.lock(); try { x++; } finally { lock.unlock(); } } }
Java Concurrent APIs o Read/Write Locks o Used with the scenario where multiple readers present with only one writer. o Keeps a pair of locks, one for “read-only” operations and one for writing o Practical Example : TenantAxisUtils -> reading vs terminating tenant axisConfigurations.
Java Concurrent APIs o Executors o Thread creation and management itself is a separate task when it comes to large scale applications. o Three main categories - Executor Service - Thread Pools - Fork/Join
Java Concurrent APIs o Executors Interfaces 1. ExecutorService, help manage lifecycle of the individual tasks. 2. ScheduledExecutorService, supports periodic execution of tasks. o Practical example : CarbonDeploymentSchdularTask
Java Concurrent APIs o Thread Pool o Manage a pool of worker threads. o Reduces the overhead due to new thread creation. o Create thread pools using the factory methods of java.util.concurrent.Executors. o Example : Tomcat Listener Thread Pool, Synapse Worker Thread pool
Java Concurrent APIs o Fork/Join o From Java 7 onwards. o Helps to take advantage of multi-processor system. o Break a large task into small tasks and execute them parallelly o Example : Count total number of prime numbers between 1 to 1000. o java.util.streams package uses implementation of fork/join framework.
Java Concurrent APIs o Concurrent Collections o Help avoid memory consistency errors o ConcurrentMap ■Subinterface of Map with atomic map operations. ■Practical Example : Axis2 Deployer Map (uses ConcurrentHashMap) o Blocking Queue ■FIFO data structure that blocks or times out when adding to a full queue, or get from an empty queue
Java Concurrent APIs o Atomic Variables o Supports atomic operations on variables o Practical Example : ClusterMessage on Repository Update. public class Example { private AtomicInteger x = new AtomicInteger(0); public void increment() { x.incrementAndGet(); } public int getValue() { return x.get(); } }
Questions ?

Basics of Java Concurrency

  • 1.
  • 2.
    Agenda o Why Concurrency? oProcesses and Threads o Java Thread Example o Thread Safety o Race Conditions & Critical Sections o Java Synchronization o Deadlock, Starvation o Java Concurrent APIs
  • 3.
    Why Concurrency? o Benefits oMake use of multi processor system o Handle asynchronous behaviour (eg : Server) o Better responsive applications (eg : UI)
  • 4.
    Why Concurrency? o Risks oThread safety o Deadlocks, starvation o Performance overhead
  • 5.
    Processes and Threads oProcess o Runs independently of other processes and has separate memory space. o Thread o Also runs independently of other threads, but can access shared data of other threads in the same process. oA Java application at least has one thread (main)
  • 6.
    Java Thread Example oThread subclass public class ExampleThread extends Thread { @Override public void run() { System.out.println("Hello !!!"); } } ExampleThread thread = new ExampleThread(); thread.start();
  • 7.
    Java Thread Example oImplement “Runnable” interface public class ExampleRunnable implements Runnable { @Override public void run() { System.out.println("Hello !!!"); } } Thread thread = new Thread(new ExampleRunnable()); thread.start();
  • 8.
    Java Thread Example oCommon mistake with threads Calling run() instead of start() This will not start a new thread, instead the run() method will be executed by the same thread.
  • 9.
    Java Thread Example oPausing a thread Thread.sleep(5000); Example : Cluster initialization o Interrupting a thread ExampleThread thread = new ExampleThread(); thread.start(); thread.interrupt();
  • 10.
    Java Thread Example othread.join(): wait on another thread for completion The join method allows one thread to wait for the completion of another.
  • 11.
    Java Thread Example oThreadLocal o used with variables that can only be accessed (read and write) by the same thread. public class ExampleThreadLocal { public static class ExampleRunnable implements Runnable { private ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(); @Override public void run() { threadLocal.set((int) (Math.random() * 500)); System.out.println("Thread Local Variable Value : " + threadLocal.get()); } } public static void main(String[] args) { ExampleRunnable runnable = new ExampleRunnable(); Thread t1 = new Thread(runnable); Thread t2 = new Thread(runnable); t1.start(); t2.start(); } }
  • 12.
    Java Thread Example oThreadLocal o Practical example : CarbonContext oThread Signalling o wait(), notify() and notifyAll()
  • 13.
    Thread Safety o Ifmultiple threads access (read or write) the same variable (or a code section) without proper synchronization, the application is not thread safe. o Don't share mutable variable between threads or make the variable immutable. o Synchronize the access of the variable.
  • 14.
    Race Condition &Critical Sections o If two threads try to compete for same resource and if the order in which the resource is accessed is of interest, then there arise a race condition. oA resource (code section) that leads to race conditions is called a critical section.
  • 15.
    Race Condition &Critical Sections public class Example { private int x = 0; public void increment() { x++; } }
  • 16.
    Race Condition &Critical Sections o Single expression composed of multiple steps - Thread Interference o Inconsistence view of the value - Memory consistency error
  • 17.
    Java Synchronization public classExample { private int x = 0; public synchronized void increment() { x++; } public synchronized int getValue() { return x; } }
  • 18.
    Java Synchronization o Notwo threads can execute synchronized methods on the same object instance. - Locks on objects. o Changes to the object within synchronized section are visible to all threads. - Resumed threads will see the updated value
  • 19.
    Java Synchronization o Thesynchronized keyword can be used with the following: o Instance methods or code segment blocks within instance methods o Static methods or code segment blocks within static methods
  • 20.
    Java Synchronization o Synchronizedstatements public void increment() { synchronized (this) { x++; } }
  • 21.
    Java Synchronization o Useof “static” public class Example { public static synchronized void sayHello1() { System.out.println("Hello1 !!!"); } public static void sayHello2() { synchronized (Example.class) { System.out.println("Hello2 !!!"); } } }
  • 22.
    Java Synchronization o ReentrantSynchronization A thread can acquire lock already owned by it self. public class Example { public synchronized void sayHello1() { System.out.println("Hello1 !!!"); sayHello2(); } public void sayHello2() { synchronized (this) { System.out.println("Hello2 !!!"); try { Thread.sleep(2000); } catch (InterruptedException e) { System.out.println("I was interrupted !!!"); } } } }
  • 23.
    Deadlock & Starvation oDeadlock o Two or more threads are blocked forever, waiting for each other. o Occur when multiple threads need the same locks, at the same time, but obtain them in different order. Thread 1 locks A, waits for B, Thread 2 locks B, waits for A o Practical Example : Issue found with CarbonDeploymentSchedulerTask and ClusterMessage o Starvation o A thread is not given regular access to CPU time (shared resources) because of other threads.
  • 24.
    Deadlock & Starvation oDeadlock Prevention o Order how the locks can be acquired o Use locks instead of synchronized statements (fairness)
  • 25.
    Java Concurrent APIs oFound under java.util.concurrent o High level concurrency objects o Locks o Executors o Concurrent Collections o Atomic variables
  • 26.
    Java Concurrent APIs oLocks Lock lock = …... lock.lock(); try { // critical section } finally { lock.unlock(); }
  • 27.
    Java Concurrent APIs oReentrantLock o Provide reentrant behaviour, same as with synchronized blocks, but with extended features (fairness). public class LockExample { private Lock lock = new ReentrantLock(); private int x = 0; public void increment() { lock.lock(); try { x++; } finally { lock.unlock(); } } }
  • 28.
    Java Concurrent APIs oRead/Write Locks o Used with the scenario where multiple readers present with only one writer. o Keeps a pair of locks, one for “read-only” operations and one for writing o Practical Example : TenantAxisUtils -> reading vs terminating tenant axisConfigurations.
  • 29.
    Java Concurrent APIs oExecutors o Thread creation and management itself is a separate task when it comes to large scale applications. o Three main categories - Executor Service - Thread Pools - Fork/Join
  • 30.
    Java Concurrent APIs oExecutors Interfaces 1. ExecutorService, help manage lifecycle of the individual tasks. 2. ScheduledExecutorService, supports periodic execution of tasks. o Practical example : CarbonDeploymentSchdularTask
  • 31.
    Java Concurrent APIs oThread Pool o Manage a pool of worker threads. o Reduces the overhead due to new thread creation. o Create thread pools using the factory methods of java.util.concurrent.Executors. o Example : Tomcat Listener Thread Pool, Synapse Worker Thread pool
  • 32.
    Java Concurrent APIs oFork/Join o From Java 7 onwards. o Helps to take advantage of multi-processor system. o Break a large task into small tasks and execute them parallelly o Example : Count total number of prime numbers between 1 to 1000. o java.util.streams package uses implementation of fork/join framework.
  • 33.
    Java Concurrent APIs oConcurrent Collections o Help avoid memory consistency errors o ConcurrentMap ■Subinterface of Map with atomic map operations. ■Practical Example : Axis2 Deployer Map (uses ConcurrentHashMap) o Blocking Queue ■FIFO data structure that blocks or times out when adding to a full queue, or get from an empty queue
  • 34.
    Java Concurrent APIs oAtomic Variables o Supports atomic operations on variables o Practical Example : ClusterMessage on Repository Update. public class Example { private AtomicInteger x = new AtomicInteger(0); public void increment() { x.incrementAndGet(); } public int getValue() { return x.get(); } }
  • 35.