Skip to main content

Posts

Showing posts from November 10, 2018

Java Concurrency - Intrinsic Lock & Reentrancy

Greetings! Any Java object can implicitly act as a lock for purposes of synchronization. These built-in locks are intrinsic locks. Java provides synchronized block as a built-in locking mechanism to enforce atomicity. Java built in object lock is called Intrinsic Lock. synchronized (lock) { // shared data } When use in method level, invoking object is the lock. Act as a mutex (only one thread at a time) Lock is acquired by the executing thread before entering a synchronized block. Reentrancy Thread owning a lock can again acquire the lock is called reentrant lock. Can claim the lock multiple time without blocking itself. Without reentrant lock, there will be a dead lock. Intrinsic locks are re-entrant. Locks are acquired on a per-thread basis rather than per-invocation basis. Every shared, mutable state should be guarded by the same lock.

Java Concurrency - join()

Greeting! Let's see the output of below program first. public class ThreadJoin { public static void main(String[] args) { System.out.println("start"); Thread t1 = new Thread(() -> System.out.println("in t1")); Thread t2 = new Thread(() -> System.out.println("in t2")); t1.start(); t2.start(); System.out.println("end"); } } start end in t1 in t2 Notice that start and end print before it prints the messages from the threads. This is because thread are running separately hence main thread executes immediately. What if we want to print end after executing t1 and t2? We can ask main thread to wait for finishing t1 and t2. It is like a relay race. Second runner is waiting for the first runner to come and hand over the flag to him. join - execution thread put on wait until this thread is finished. public class ThreadJoin { public static void main(String[] args) {

Java Concurrency - Race Conditions - Read-Modify-Write

Greetings! When two or more threads access shared data at the same time race condition occurred. These operation should be atomic to thread-safe and we call them "compound actions". read-modify-write - read a value, modify it, write back (ex: increment a value). check-then-act - check a condition and act accordingly; common situation is lazy initialization (ex: singleton pattern). In this blog post we are going to examine read-modify-write race condition. Let's say we need a counter and we designed below class. public class Counter { private int count = 0; public int getAndIncrement() { return count++; } public int get() { return count; } } Can you spot a possible bug here? Well, for a single threaded application this is working fine. But for a multi-threaded application this will give unexpected results. Problem here is count++ is not an atomic operation. Let's create few threads and see the results. imp

Java Concurrency - How To Create A Thread

Greetings! It is easy to create a thread in Java using 2 well known methods. extends Thread class. implement Runnable interface. Then we create a Thread object and start it! It is as simple as that. public class ExtendThread extends Thread { @Override public void run() { System.out.println("hello from extended thread"); } } Thread thread = new ExtendThread(); thread.start(); public class ImplmentedRunnable implements Runnable { @Override public void run() { System.out.println("hello from runnable implementation"); } } Thread thread = new Thread(new ImplmentedRunnable()); thread.start(); In Java 8; Thread thread = new Thread(() -> System.out.println("hello from java 8")); thread.start(); It is not a good practice to extend the Thread class. Thread states. A thread exist in several states. New - when we create an instance of Thread class it is in New state. Run

Java Concurrency - Thread Safety

Greetings! What is thread safety? When we have multiple threads accessing piece of code simultaneously without unwanted side effects we can say our code is thread safe. Correctness!!! Synchronization Synchronization allows to control the program flow and access to shared data for concurrently executing threads. It is tempting to think synchronized is the only way to do this in Java but it is the primary mechanism which provides exclusive locking. volatile variable, explicit locks and atomic variables are other types. We can synchronize using; mutex lock - allow only one thread at a time to execute a specific section of code (critical section !!) read/write lock - permit concurrent reads and exclusive writes to a protected shared resource. condition variable - block threads until a particular condition is true. semaphore - simply a variable which is a count (counting semaphore) or 0/1 switch (binary semaphore). How to share mutable state between threads? Don't

Java Concurrency - Introduction

Greetings! We can sing while having a bath. We can listen to song while jogging. We are multitasking!. Can a computer to do that? How can a computer do that? As a developer how do we do that?   Process vs Thread Let's take word processor as an example. In a word processor there are spell checker, auto correct, etc. Which means within Word application there are sub tasks are running behind the scene. And those tasks share the same address space as the process. We name those sub tasks as Threads and main task as a Process. Back in old days, a computer had only one CPU. On the other hand computer could handle only one task at a time. It switch between tasks very quickly so that we can't see the difference. ( Time Slice ) Modern computers come with multiple processors allowing multiple tasks to run at the same time. When dealing with multiple threads we have to think; Two threads update a variable simultaneously. One threads depends on another thread. Two threads

Java Collections - Lists

Greetings! It is probably Lists are the most used Collections. Can have duplicates. Maintain the element order. Can iterate in added order. Lists maintain the added order. Hence it can be accessed by given position. List interface have additional methods to fulfill this requirement. // add, remove in given position void add(int index, E e) E get(int index) E remove(int index) E set(int index, E e) // search position by object int indexOf(Object o) int lastIndexOf(Object o) // get a sub list by given positions (toIndex exclusive) List<E> subList(int fromIndex, int toIndex) // get listiterator ListIterator<E> listIterator() subList doesn't return a new list. It returns a view of the existing list by given positions. Because of this changing the original list changes the sub list. But changing the sub list doesn't affect the original list. ConcurrentModificationException can be occurred if the original list is changed and try access the sub list. Li

Java Collections - Interfaces

Greetings! There are number of data structures. To handle varies kind of collections, Collection framework has different interfaces. Collection - fundamental interface for most of the collections Set  - no duplicates. no order. List - ordered collection. contain duplicates. can access using position. Queue - typically has first-in-first-out structure. Deque - double-ended queue. can behave both as first-in-first-out and last-in-last-out. can insert and remove from both ends. SortedSet - maintain sort order Map - contains key-value pairs. no duplicates allowed. SortedMap - maintain sorted key order Collection Interface Map Interface Iterator Other than that, there is RandomAccess interface.

Java Collections - Collection Interface

Greetings! Collection interface is the base interface for most of the classes in Collection Framework. It mainly contains methods for add, remove and iteration. public interface Collection<E> { boolean add(E element); Iterator<E> iterator(); boolean remove(Object o); // .... } Other than that this contains a lot of common utility methods. int size() boolean isEmpty() boolean contains(Object obj) boolean containsAll(Collection<?> c) boolean equals(Object other) boolean addAll(Collection<? extends E> from) boolean remove(Object obj) boolean removeAll(Collection<?> c) void clear() boolean retainAll(Collection<?> c) Object[] toArray() <T> T[] toArray(T[] arrayToFill) Java 8 has introduced new default methods to convert the Collection into a stream. default Stream<E> stream() default Stream<E> parallelStream() default boolean removeIf(Predicate<? super E> filter) There is no concrete impleme

Java Collections - ConcurrentModificationException

Greetings! When you use a collection and suddenly encounter ConcurrentModificationException it is very confusing. Why are we getting this when we are not using multi-threading? Actually this doesn't mean you are using multi-threading. This means that the collection in used is modified (add/remove). For an example let's say we want remove multiples of 3 from an array list. List<Integer> numbers = IntStream.range(1, 20).boxed().collect(toList()); for (Integer number : numbers) { if (number % 3 == 0) { numbers.remove(number - 1); } } This little program will throw java.util.ConcurrentModificationException because we are modifying the collection directly while iterating. Underline iterator is implemented so that it checks for any modification. If it found any modification it throws new ConcurrentModificationException. Instead of removing items from the collection, we need to remove it from the iterator. List<Integer> numbers = IntStre

Java Collections - Iterable and Iterator

Greetings! It is easily misunderstand that Collection interface is the super interface in JCF. Actually, Collection interface extends Iterable interface. public interface Iterable<T> { Iterator<T> iterator(); } Idea of this is to give a common way traverse the underline collection using the Iterator. public interface Iterator<E> { boolean hasNext(); E next(); void remove() } Prior to Java 5, for loop was used as below, for (Iterator iterator = collection.iterator(); iterator.hasNext(); ) { iterator.next(); } With Java 5 foreach loop, iterators are used internally by the compiler and it is simplified. for (SomeObject object : collection) { // .... } With Java 8 lambda expressions both Iterable and Iterator interfaces are updated to simplify this even more. iterator.forEachRemaining(element -> { // do something }); collection.foreach(element -> { // do something }); next() and remove()

Java Collections - Introduction

Greetings! We have to use different kind of data structures and algorithms in our code. Luckily for us, Java provide Java Collection Framework (JCF) for that purpose. Prior to Java 1.2 Java had only few data structures like Vector, Stack, Hashtable, Enumeration. Java 2 introduced proper collection API to address all data structures issues. Easy to use collections. High performance. Easy to extend. There is no "one for all" implementation. Common Interfaces Iterable - provide iteration through a collection. (this is outside of the api) Collection - main interface for the most of the collections. contains most of the core functionalities. Set - can not have duplicate. contains unique elements. doesn't maintain the insertion order. List - maintain the order. can have duplicates. Queue - define first in first out data structure. Map - key, value pairs. In Collection API, interfaces provide the necessary contract but it doesn't give us an idea abou