Archive

Archive for January, 2016

Thread Tracer

January 24, 2016 Leave a comment

This program can be integrated with your any java program to trace various states of a thread. It can help you to understand the flow of a thread. But remember, Tracer runs a thread to trace states of a thread. Tracer will not able to print all states of a thread. since there might be a situation when Tracer thread get served to CPU very late or with big interval and another thread changes its 3-4 states in between. I generally run Tracer 2-3 times for proper understanding.

I took its help to find out deadlock in my one of the program over nested monitor.


import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.sql.Timestamp;
import java.util.ArrayList;

public class Tracer {
    private ArrayList <WrapperThread> threadList;

    Tracer() {
        threadList = new ArrayList < WrapperThread > ();
    }
 
    public void add(Thread t) {
        threadList.add(new WrapperThread(t));
    }
 
    static {
        new Thread(() -> {
                System.out.println("Monitoring Deadlocks");
                while (Thread.activeCount() >= 2) deadLockMonitor();
        }, "DeadLock Monitor").start();
    }
 
    private static void deadLockMonitor() {
        ThreadMXBean mx = ManagementFactory.getThreadMXBean();
        long[] DevilThreads = mx.findDeadlockedThreads();
        if (DevilThreads != null && DevilThreads.length > 0) {
            System.out.println(currentTime() + " :: Deadlock detected");
            for (int i = 0; i < DevilThreads.length; i++) {
                System.out.println("Thread id :" + DevilThreads[i]);
            }
            System.out.println("Exiting from system");
            System.exit(0);
        }
    }
 
    public void trace() {
        new Thread(() -> {
                while (Thread.activeCount() >= 2) {
                    if (isStateChanged()) System.out.println (currentTime() + " :: "+threadList);
                }
        }, "Tracer").start();
    }
 
    private boolean isStateChanged(){
    	for (WrapperThread wT : threadList) {
    		if(wT.isStateChanged()) return true;
	}
    	return false;
    }
 
    public static String currentTime() {
        return (new Timestamp(System.currentTimeMillis())).toString();
    }
}

Wrapper Thread

import java.lang.Thread.State;

public class WrapperThread{
	private String name;
	protected Thread originalThread;
	private State lastState;

	public WrapperThread(Thread t) {
		originalThread = t;
		name = t.getName();
		lastState = originalThread.getState();
		System.out.println(Tracer.currentTime() + " :: " + this);
	}

	public boolean isStateChanged() {
		State state = originalThread.getState();
		if(lastState != state){
			lastState = state;
			return true;
		}
		return false;
	}

	public State currentState() {
		return originalThread.getState();
	}
	
	@Override
	public String toString() {
		return name+":"+currentState();
	}
}

How to use it in your program

Tracer t = new Tracer();
t.add(A);
t.add(B);
t.trace();

Happy coding 🙂

Categories: Java, Multithreading

CyclicBarrier

January 23, 2016 Leave a comment

CyclicBarrier = Cycle + Barrier

CyclicBarrier just force threads to wait until their count reached to N. Then release them to run on a wide road. And force next N threads to wait. and so on.

 

public class CycleBarrierDemo implements Runnable {
    CyclicBarrier controller;

    CycleBarrierDemo() {
        controller = new CyclicBarrier(1);
    }
    @Override
    public void run() {
        try {
            Thread.sleep(100);
            System.out.println(controller.getNumberWaiting());
            System.out.println(Thread.currentThread().getName() + " has been arrived");
            controller.await();
            System.out.println(Thread.currentThread().getName() + " has been Passed");
        } catch (Exception bbx) {
            System.out.println(bbx.getMessage());
        }
    }
    public static void main(String[] argc) {
        CycleBarrierDemo cd = new CycleBarrierDemo();
        Thread A = new Thread(cd, "A");
        Thread B = new Thread(cd, "B");
        Thread C = new Thread(cd, "C");
        Thread D = new Thread(cd, "D");

        A.start();
        B.start();
        C.start();
        D.start();
    }
}

Output: [When barrier size was 1]

0
A has been arrived
A has been Passed
0
B has been arrived
B has been Passed
0
C has been arrived
C has been Passed
0
D has been arrived
D has been Passed

Output:[When barrier size was 2]

A has been arrived
1
B has been arrived
A has been Passed
B has been Passed
0
C has been arrived
1
D has been arrived
C has been Passed
D has been Passed

Categories: Java, Multithreading

Java Multithreading – Final program

January 23, 2016 Leave a comment

I code this program to explain Condition in java. Further I extended it to explain the use of

  • Executor & ExecutorServices to make ThreadPool.
  • Use of Future Object & Callable interface to enquiry/communicate with running thread.
  • Use of Semaphore to control number of threads.
  • Lock over synchronized block
  • Threads inside threads
  • Enum & EnumMap to store well known values.
  • Condition (labelled wait & notify) to notify thread waiting for specific condition.

Condition

condition (since Java 5) is nothing but labeled wait(), notify() & notifyAll(). Let’s understand it with an example;

There are 2 containers: ChocoPowederContainer, WheatPowderContainer. CookieMaker takes some amount of powder from both containers to make a ChocoWheatCookie. There is a Filler who checks container with regular interval. If he finds any container empty, he fills it.

Condition:

  1. CookieMaker starts N threads say maker1, maker2,.. makerN  to produce cookies.
  2. maker5, maker6, and maker9 found ChocoPowederContainer empty. They took powder from WheatPowderContainer.
  3. maker13, maker10, and maker7 found WheatPowderContainer empty. They took powder from ChocoPowederContainer.
  4. Filler finds ChocoPowederContainer empty. So he filled it and notifyAll() makers. After sometime Filler finds another container empty and fills it and notifyAll() again.

But maker13, maker10, and maker7 want to be notified only when WheatPowderContainer get filled. And maker5, maker6, and maker9 want to be notified only when ChocoPowederContainer get filled.

For the solution, Filler can make 2 Condition objects, say ChocoPowederContainerEmpty and  WheatPowderContainerEmpty. maker5, maker6, and maker9 will call ChocoPowederContainerEmpty.await() and maker13, maker10, and maker7 will call WheatPowderContainer.await().

Filler will call WheatPowderContainerEmpty.signalAll() once WheatPowderContainer is filled. And so on.

Final Code

Cookie class: First I developed this code with this class then I omitted it. Because this class does nothing but getting/setting an EnumMap. So I directly moved this EnumMap into CookieMaker class


public class Cookie {
    EnumMap &lt; Ingredient, Integer &gt; ingredients;

    Cookie() {
        ingredients = new EnumMap &lt; Ingredient, Integer &gt; (Ingredient.class);
    }

    public void setIngredient(Ingredient i, int quantity) {
        ingredients.put(i, quantity);
    }

    public EnumMap &lt; Ingredient, Integer &gt; getIngredients() {
        return ingredients;
    }
}

IngredientContainer Class – represents a container with some method to fill & consume container ingredient. As per the problem, a maker thread should wait if container is empty. If thread A waits for container 1 and B waits for container 2 and Filler fills container 1 then only thread A should be notified. So I have attached Condition object with container class itself.

 


public class IngredientContainer {
    private int capacity; //How much quantity of an ingredient a container can have
    private int quantityHeld;
    Condition empty;

    IngredientContainer(int c) {
        capacity = c;
    }

    //getters

    public int getQuantityRequired() {
        return capacity - quantityHeld;
    }

    public void fill(int n) throws Exception {
        if ((n + quantityHeld) &gt; capacity) {
            throw new Exception("Overfilled");
        }
        quantityHeld += n;
    }

    public boolean isEmpty() {
        return quantityHeld == 0;
    }
    /**
     *
     * @param n filled units
     * @return
     */
    public int fillSafe(int n) {
        int require = capacity - quantityHeld;
        int toBeFilled = Math.min(require, n);
        quantityHeld += toBeFilled;
        return toBeFilled;
    }

    public void setEmptyCondition(Condition c) {
        this.empty = c;
    }
    public boolean getIngredient(int n) throws Exception {
        if (n &gt; capacity) {
            throw new Exception("Accessing quantity more than capacity");
        }
        if (quantityHeld &gt;= n) {
            TimeUnit.SECONDS.sleep(1);
            quantityHeld -= n;
            return true;
        }

        System.out.println("Less Quantity Held");
        return false;
    }
}

Filler class – One filler is associated with one maker in our program who keeps watch on containers of associated maker only. And fills them.

 


import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/*
* Filler checks a Container with regular interval. Either it fills Container
* safely or check it before filling it.
*
* @author Amit Gupta
*/
public class Filler {
    private ArrayList &lt; IngredientContainer &gt; ingredientContainers;
    int capacity = 6;
    private int checkInterval = 3;
    private int fillingQuantity = 2;
    private boolean isInterrupted = false;
    private Lock containerLock;

    public Filler(int c, Lock l) {
        ingredientContainers = new ArrayList &lt; IngredientContainer &gt; ();
        capacity = c;
        containerLock = l;
    }

    public void addContainer(IngredientContainer c) throws Exception {
        if (ingredientContainers.size() == capacity)
            throw new Exception("Filler is overloaded");
        ingredientContainers.add(c);
    }
    /**
     * Filler checks container with regular interval and fills if it is empty.
     * @author Amit Gupta
     */
    public void startFilling() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Filler has started working");
                while (!isInterrupted) {
                    try {
                        TimeUnit.SECONDS.sleep(checkInterval);
                        System.out.println("Filler starts checking containers");
                        containerLock.lock();
                        Iterator &lt;IngredientContainer&gt; itr = ingredientContainers.iterator();
                        while (itr.hasNext()) {

                            IngredientContainer ingredientContainer = itr.next();
                            System.out.println("Require : " + ingredientContainer.getQuantityRequired());
                            System.out.println("Capacity : " + ingredientContainer.getCapacity());
                            System.out.println("Filling : " + fillingQuantity);

                            int filledQ = ingredientContainer.fillSafe(fillingQuantity); //Try to fill required quantity only.
                            System.out.println("Filled " + filledQ);
                            ingredientContainer.empty.signalAll(); //This condition must be instantiate from CookieMaker

                        }
                        containerLock.unlock();
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                }
            }
        }).start();
    }

    public void stopFilling() {
        isInterrupted = true;
    }
    /**
     * How long Filler should wait checking a container.
     * @param checkInterval Seconds. default is 3 seconds.
     */
    public void setCheckInterval(int checkInterval) {
        this.checkInterval = checkInterval;
    }

    /**
     * How much quantity should be filled in a container, if it is empty.
     * @param fillingQuantity default 10.
     */
    public void setFillingQuantity(int fillingQuantity) {
        this.fillingQuantity = fillingQuantity;
    }
}

CookieMaker class – This is heart of the program. All other classes are created to support this class. It seems little bit complex. So we’ll understand it into parts.

 


import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/*
* CookieMaker bakes N cookies at a time. He can bake 1 type of cookie only
* Required containers must be installed in prior to bake a cookie.
*
* @author Amit Gupta
*
*/

public class CookieMaker implements Runnable {
    EnumMap &lt; Ingredient, IngredientContainer &gt; containers;
    int containerCapacity = 0; //How many containers a maker can have
    Semaphore bakingCapacity; //How many cookies a maker can bake
    EnumMap &lt; Ingredient, Integer &gt; cookie;
    private Lock bakingLock = new ReentrantLock();
    private Lock containerLock = new ReentrantLock();
    Filler fillingWorker = new Filler(6, containerLock);

    public void addContainer(Ingredient i, IngredientContainer c) throws Exception {
        //System.out.println("Adding " + i.toString() + " container.");
        if (containers.size() == containerCapacity) {
            throw new Exception("Containers over loaded");
        }
        c.setEmptyCondition(containerLock.newCondition());
        //System.out.println("Condition is added to Container");
        fillingWorker.addContainer(c);
        //System.out.println("Container is added to Filler");
        containers.put(i, c);
        System.out.println(i.toString() + "container added");
    }

    public void StartBaking() {
        try {
            System.out.println(bakingCapacity.getQueueLength() + " are waiting");
            bakingCapacity.acquire();
            System.out.println(bakingCapacity.availablePermits() + " more threads can enter");
            bakingLock.lock();
            System.out.println(Thread.currentThread().getName() + " :: Entered.");
            Set &lt; Ingredient &gt; ingredients = cookie.keySet();
            Iterator &lt; Ingredient &gt; itr = ingredients.iterator();
            ExecutorService pool;
            Set &lt; Future &lt; Boolean &gt;&gt; tasks = new HashSet &lt; Future &lt; Boolean &gt;&gt; ();

            try {
                pool = Executors.newFixedThreadPool(containers.size());
                while (itr.hasNext()) {
                    System.out.println();
                    final Ingredient ingredient = itr.next();
                    tasks.add(pool.submit(new Callable &lt; Boolean &gt; () {@
                        Override
                        public Boolean call() throws Exception {
                            return getIngredient(ingredient);
                        }
                    }));
                }
                Iterator &lt; Future &lt; Boolean &gt;&gt; fuItr = tasks.iterator();
                boolean tasksCompleted = true;

                while (fuItr.hasNext()) {
                    Future &lt; Boolean &gt; f = fuItr.next();
                    tasksCompleted &amp;= f.get();
                }
                if (tasksCompleted) {
                    System.out.println("Mixture is ready. Backing cookie");
                    pool.shutdown();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            System.out.println("Thread " + Thread.currentThread().getName() + " :: completed");
            bakingLock.unlock();
            bakingCapacity.release(); //let other threads start baking
            fillingWorker.stopFilling();
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
    }

    /**
     * Take ingredients from a container. Wait if container is empty.
     * @param ingredient
     * @return
     * @throws Exception
     * @throws InterruptedException
     */
    private boolean getIngredient(final Ingredient ingredient) throws InterruptedException, Exception {
        containerLock.lock();
        System.out.println("sub thread for " + ingredient.toString());
        IngredientContainer container = containers.get(ingredient);
        System.out.println(ingredient.toString() + " Container has " + container.getQuantityHeld());
        int quantity = cookie.get(ingredient);
        System.out.println("sub thread : Quantity require:" + quantity);
        while (!container.getIngredient(quantity)) {
            container.empty.await();
        }
        //In real world I believe, this method will take some time to take ingredients from a container.
        TimeUnit.SECONDS.sleep(1);
        System.out.println("subThread " + ingredient.toString() + " has completed");
        containerLock.unlock();
        return true;

    }

    public static void main(String[] args) {
        IngredientContainer chocoPowderContainer = new IngredientContainer(12);
        IngredientContainer wheatPowderContainer = new IngredientContainer(15);

        CookieMaker cm = new CookieMaker(4, 5);
        EnumMap &lt; Ingredient, Integer &gt; chocoWheatBar = new EnumMap &lt; Ingredient, Integer &gt; (Ingredient.class);

        chocoWheatBar.put(Ingredient.ChokoPowder, 3);
        chocoWheatBar.put(Ingredient.WheatPowder, 1);

        try {
            cm.addContainer(Ingredient.ChokoPowder, chocoPowderContainer);
            cm.addContainer(Ingredient.WheatPowder, wheatPowderContainer);
            cm.setCookie(chocoWheatBar);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        new Thread(cm, "maker1").start();
        new Thread(cm, "maker2").start();
        new Thread(cm, "maker3").start();
        new Thread(cm, "maker4").start();
        new Thread(cm, "maker5").start();
        new Thread(cm, "maker6").start();

        cm.fillingWorker.startFilling();

    }

    @Override
    public void run() {
        if (checkSetup()) {
            StartBaking();
        } else {
            System.out.println("Initial setup is required");
        }
    }

    public CookieMaker() {
        containers = new EnumMap &lt; Ingredient, IngredientContainer &gt; (Ingredient.class);
    }

    public CookieMaker(int bc) {
        bakingCapacity = new Semaphore(bc);
        containers = new EnumMap &lt; Ingredient, IngredientContainer &gt; (Ingredient.class);
    }

    public CookieMaker(int bc, int cc) {
        bakingCapacity = new Semaphore(bc);
        this.containerCapacity = cc;
        containers = new EnumMap &lt; Ingredient, IngredientContainer &gt; (Ingredient.class);
    }

    public void setCookie(EnumMap &lt; Ingredient, Integer &gt; cookie) {
        this.cookie = cookie;
    }

    public void setBakingCapacity(int bakingCapacity) {
        this.bakingCapacity = new Semaphore(bakingCapacity);
    }

    public void setContainerCapacity(int containerCapacity) {
        this.containerCapacity = containerCapacity;
    }

    /**
     * Checks Maker's initial set up.
     * @throws Exception
     */
    public boolean checkSetup() {
        boolean signal = false;
        /*if(bakingCapacity. &lt; 1){
        System.out.println("Maker can not bake cookies");
        }
        else*/
        if (containerCapacity &lt; 1) {
            System.out.println("Container capacity is 0");
        } else if (containers.size() &lt; 1) {
            System.out.println("No container is installed.");
        } else {
            signal = true;
        }
        return signal;
    }
}

I am not attaching output of above classes here since it is too long. I am chunking it and explaining you important parts.

bakingCapacity – Maker has the capacity of baking 4 cookies at a time. bakingCapacity semaphore keeps counting on running thread. If 4 threads are running and 1 completes its working, bakingCapacity allows 1 more thread. Review the output below;

0 are waiting
3 more threads can enter
maker1 :: Entered.
0 are waiting
2 more threads can enter
0 are waiting
1 more threads can enter
0 are waiting
0 more threads can enter
Thread maker1 :: completed
maker3 :: Entered.
0 more threads can enter
:

In above output, bakingCapacity allows 1st 4 threads to get entered. marker1 enters into its critical session. Total 4 threads are inside semaphore this time. Out of them 1 is running and other 3 are waiting. marker1 completes its work and get out from semaphore. marker3 enters into monitor. Now 2 threads are waiting and 1 is running. Total 3 threads are in semaphore. So bakingCapacity allows 1 more thread to get enter. And so on.

bakingLock: This lock ensures that only 1 thread can enter in its monitor. If you see in output you’ll notice following sequence;

maker1 :: Entered.
Thread maker1 :: completed
maker3 :: Entered.
Thread maker3 :: completed
maker5 :: Entered.
Thread maker5 :: completed
maker2 :: Entered.
Thread maker2 :: completed
maker4 :: Entered.
Thread maker4 :: completed
maker6 :: Entered.
Thread maker6 :: completed

Here the question arises if all threads are running in sequence then what is the need of multi-threading?

MultiThreadig is required when multiple tasks run parallel. And Locking is required when you fear that some other thread can change value of a variable required by current thread.

Let’s traverse each statement of StartBaking().

What type of ingredients a cookie has?
For each ingredient take required quantity from relevant container.
If 1 container is empty then take ingredient from another container and for 1st container to get filled.
Once ingredients are taken from all containers, bake cookie.
Ingredients are always fixed for a cookie type. It could be critical if a maker can produce multiple types of cookies. Moreover, local variables are always thread safe. So we need not to worry for point a).

For point b) & c), we will have to take ingredients from containers parallel. So for each container we’ll have to create one sub-thread. Containers are being filled by Filler. When a sub-thread takes ingredients from container, container’s quantity get reduced. So there is a critical condition when 2 threads check container quantity at the same time and both reduce it.

public boolean getIngredient(int n) throws Exception {
	:
    if (quantityHeld &gt;= n) {
        quantityHeld -= n;
        return true;
    }
    :
}

This section requires lock. Since we already acquiring lock in getIngredient() of Maker class. So there is no need of locking in StartBaking().

Once ingredients are taken, we don’t have to check any value which can be modified by any other thread.

containerLock – Condition discussed in above points proves the need of this lock. But we’ll analyze it.

java multithreading CookieMaker containers

Suppose marker1 creates 2 sub-threads A, B. marker2 creates C,D. All sub-threads call getIngredient() of Maker class. ChocoPowder Container has 2 units of powder while other container has 5 units. As per cookie recipe, A & C require 3 units while B & D require 1 unit.

A : enter
C: waiting
A: finds insufficient quantity in container. waits and releases lock.
C: enters
Filler : fills 2 units. So total units in ChocoPowder container are 4.
A & C both access getIngredient() of container class at the same time.
A & C both finds sufficient quantity. So both reduce quantity and come out.
Current quantity in ChocoPowder container is -2 units.
Where we require lock?

containerLock can be moved down since starting statements are creating local variables which are thread safe. Note that container is referencing field member. But its value is fixed so the next version of method could be as follows;

private boolean getIngredient(final Ingredient ingredient) throws Exception {
    IngredientContainer container = containers.get(ingredient);
    int quantity = cookie.get(ingredient);
    containerLock.lock();
    while (!container.getIngredient(quantity)) {
        container.empty.await();
    }
    containerLock.unlock();
    return true;
}

Even this move doesn’t solve the problem. Our need says that getIngredient() of container class should be accessed by only one thread at a time. So I must make it synchronized. I don’t require to synchronize fill() in our example.

This output will show that everything is fine after above changes.

A: sub thread for ChokoPowder
A: ChokoPowder Container has 0
A: sub thread : Quantity require:3
A: Less Quantity Held
B: sub thread for WheatPowder
B: WheatPowder Container has 0
B: sub thread : Quantity require:1
B: Less Quantity Held
C: sub thread for ChokoPowder
C: ChokoPowder Container has 0
C: sub thread : Quantity require:3
C: Less Quantity Held
D: sub thread for WheatPowder
D: WheatPowder Container has 0
D: sub thread : Quantity require:1
D: Less Quantity Held
Filler: Filler starts checking containers
Filler(choco): Require : 12
Filler(choco): Capacity : 12
Filler(choco): Filling : 2
Filler(choco): Filled 2
Filler(wheat): Require : 15
Filler(wheat): Capacity : 15
Filler(wheat): Filling : 2
Filler(wheat): Filled 2
A: Less Quantity Held
C: Less Quantity Held
B: subThread WheatPowder has completed
D: subThread WheatPowder has completed
Filler: Filler starts checking containers
Filler(choco): Require : 10
Filler(choco): Capacity : 12
Filler(choco): Filling : 2
Filler(choco): Filled 2
Filler(wheat): Require : 15
Filler(wheat): Capacity : 15
Filler(wheat): Filling : 2
Filler(wheat): Filled 2
A: subThread ChokoPowder has completed
C: Less Quantity Held

Mixture is ready. Backing cookie
Thread maker1 :: completed
Filler: Filler starts checking containers
Filler(choco): Require : 11
Filler(choco): Capacity : 12
Filler(choco): Filling : 2
Filler(choco): Filled 2
Filler(wheat): Require : 13
Filler(wheat): Capacity : 15
Filler(wheat): Filling : 2
Filler(wheat): Filled 2
subThread ChokoPowder has completed
Mixture is ready. Backing cookie
Thread maker2 :: completed

containerLock in Filler class : since we are creating only one thread of Filler class so there will not be another thread calling fillSafe() at the same time. Although writing it under lock is good practice. But some statements can be written out of lock as follows;

containerLock.lock();
int filledQ = ingredientContainer.fillSafe(fillingQuantity);
ingredientContainer.empty.signalAll();
containerLock.unlock();

I hope this article can explain you more about multithreading. Keep reading …

 

Categories: Multithreading

Java Multithreading – External Locks

January 23, 2016 Leave a comment

You must be aware with the need of synchronization after reading Bad synchronization leads program’s death and Synchronization – solve the mystery.

Well! synchronized has some limitations. Lets understand with this example.

 

public class DummyClass {
	private Integer age = 0;
	public void display(){
		System.out.println(Thread.currentThread().getName() + ": " + age);
	}
	public void edit(int n){
		age = n;
	}
}

public class SynchronizedLimitDemo {

	public static void main(String[] args) {
		final DummyClass dcObj = new DummyClass();
		Thread amit = new Thread(new Runnable(){
				@Override
				public void run() {
					try{
						dcObj.edit(27);
						Thread.sleep(1000);
						dcObj.display();
					}catch(InterruptedException ixp){
						System.out.println(ixp.getMessage());
					}
				}
			},"Amit Thread");

		Thread arti = new Thread(new Runnable(){
				@Override
				public void run() {
					try{
						dcObj.edit(29);
						Thread.sleep(1000);
						dcObj.display();
					}catch(InterruptedException ixp){
						System.out.println(ixp.getMessage());
					}
				}
			},"Arti Thread");

		amit.start();
		arti.start();
	}
}

In above stupid example, even if you synchronized display() & edit(), you can’t get proper output. Now see how external locking (since Java 5) can solve it.

public class DummyClass {
	private Integer age = 0;
	private Lock dataLock = new ReentrantLock();
	public void display(){
		System.out.println(Thread.currentThread().getName() + ": " + age);
		dataLock.unlock();
	}
	public void edit(int n){
		dataLock.lock();
		age = n;
	}
}

Output:
Arti Thread: 29
Amit Thread: 27

Warning: If a thread tries calling display() directly or before lock was acquired, it’ll generate run time exception. Similarly a thread can call edit() multiple times but can forget calling display(). It’ll lock the object forever.
This example is just to elaborate an advantage of Lock over synchronized.

Problem with synchronized keyword

  1. A synchronized block makes no guarantees about the sequence in which threads waiting to entering it are granted access.
  2. You cannot pass any parameters to the entry of a synchronized block. Thus, having a timeout trying to get access to a synchronized block is not possible.
  3. The synchronized block must be fully contained within a single method. It’s not possible that synchronization starts in one method and ends in another.
  4. If a thread meets synchronized block, where another thread already had entered into it, it is supposed to wait until another thread release the lock.

Java 5 provides another locking mechanism. Where

  1. A thread can request to acquire a lock with timeout period. If lock is not acquired then thread can do something else or can request again.
  2. A Lock can be started in one method and can end in another.
How to

synchronized


method(
	synchronized(this){
		//critical section
	}
}

Lock

Lock lock = new ReentrantLock();

method(
	lock.lock();
	//critical section
	lock.unlock();
}

* It is good to call unlock() in finally block.

 

Methods

The Lock interface has the following primary methods:

  • lock()
  • lockInterruptibly()
  • tryLock()
  • tryLock(long timeout, TimeUnit timeUnit)
  • unlock()

The lock() method locks the Lock instance if possible. If the Lock instance is already locked, the thread calling lock() is blocked until the Lock is unlocked.

The lockInterruptibly() method locks the Lock unless the thread calling the method has been interrupted. Additionally, if a thread is blocked waiting to lock the Lock via this method, and it is interrupted, it exits this method calls.

The tryLock() method attempts to lock the Lock instance immediately. It returns true if the locking succeeds, false if Lock is already locked. This method never blocks.

The tryLock(long timeout, TimeUnit timeUnit) works like the tryLock() method, except it waits up the given timeout before giving up trying to lock the Lock.

The unlock() method unlocks the Lock instance. Typically, a Lock implementation will only allow the thread that has locked the Lock to call this method. Other threads calling this method may result in an unchecked exception (RuntimeException).

Note:
If you have locked an object N times you will have to call unlock() N times.

Categories: Multithreading

Java Multithreading – join

January 23, 2016 Leave a comment

Lets start with some example

method(){
	Statement 1
	Statement 2
}

If Statement 1 is a thread statement then Statement 2 can be executed any time. It doesn’t wait Statement 1 to be completed.
If Statement 1 is simple statement then Statement 2 can’t be executed until Statement 1 is completed.
If Statement 1 is a thread statement calling join() then Statement 2 can’t be executed until Statement 1 is completed.
If Statement 1 is a thread statement calling join(n) then Statement 2 can’t be executed until Statement 1 is completed or time n is over.

 


public class JoinDemo extends Object {
	public static Thread createThread(String name, long napTime) {
		final long sleepTime = napTime;

		Runnable r = new Runnable() {
			public void run() {
				try {
					print("in run() - entering");
					Thread.sleep(sleepTime);
				} catch ( InterruptedException x ) {
					print("interrupted!");
				} finally {
					print("in run() - leaving");
				}
			}
		};

		Thread t = new Thread(r, name);
		t.start();

		return t;
	}

	private static void print(String msg) {
		String name = Thread.currentThread().getName();
		System.out.println(name + ": " + msg);
	}

	public static void main(String[] args) throws Exception{
		Thread[] t = new Thread[2];
		t[0] = createThread("thread A", 2000);
		//t[0].join();
		t[1] = createThread("thread B", 1000);

	}
}

Explanation:

When createThread() get called it creates a thread. Thread.sleep() interrupts this thread. So another createThread() call takes place.

t[0] = createThread("thread A", 2000); //statement 1
t[1] = createThread("thread B", 1000); //statement 3

Output:
thread A: in run() – entering
thread B: in run() – entering
thread B: in run() – leaving
thread A: in run() – leaving

t[0] = createThread("thread A", 2000); //statement 1
t[0].join(); //statement 2
t[1] = createThread("thread B", 1000); //statement 3

Output
thread A: in run() – entering
thread A: in run() – leaving
thread B: in run() – entering
thread B: in run() – leaving

In above condition, first t[0] will be completed then statement 3 will be called.

 

Categories: Multithreading

Synchronization

January 20, 2016 Leave a comment

When a thread starts working on some critical work he locks the room (say monitor) using synchronized keyword. So no other thread can enter into the room until the current thread finish his work.

You can synchronized either an object or a method in following ways

1. Synchronize an object

public void run() {
	synchronized(target) { // synchronized object
	:
	}
}

2. Synchronize a method

public synchronized void myMethod() {
	:
}
//or
public void myMethod() {
	Synchronized(this){
	:
	}
}

Note :

If you are synchronizing a static method then it’ll take lock over complete class.
If you place synchronized block over the same object on multiple places and one of the thread had already entered into one of them, no other thread can enter into any of the synchronized block until first thread comes out.

public class SynchoTest {
	private Integer a = 10;

	public void acquire(){
		synchronized(a){
			print("acquire()");
			try{
				Thread.sleep(10000);
				print("I have awoken" + a);
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
		print("Leaving acquire()");
	}

	public void modify(int n){
		this.a=n;
		print("new value" + a);
	}

	public void display(){
		print("a=" + a);
	}
	:
}

For above program, I am starting 3 threads. Thread A calls method acquire(), Thread B calls modify(97), and Thread C calls display().

Output:

2012-03-06 07:48:10.038 :: A: acquire()
2012-03-06 07:48:10.038 :: B: new value97
2012-03-06 07:48:10.038 :: C: a=97
2012-03-06 07:48:20.054 :: A: I have awoken
2012-03-06 07:48:20.054 :: A: 97
2012-03-06 07:48:20.054 :: A: Leaving acquire()

What have you noticed in above output? When A entered in his critical section, a’s value was 10. But when it went to print it, B already changed a’s value. So A prints new value of a ie 97.

Now do some small changes

public void modify(int n){
	print("Entered in modfy");
	synchronized(a){
		this.a=n;
		print("new value" + a);
	}
}

Output:

2012-03-06 07:51:46.19 :: A: acquire()
2012-03-06 07:51:46.19 :: B: Entered in modfy
2012-03-06 07:51:46.19 :: C: a=10
2012-03-06 07:51:56.206 :: A: I have awoken
2012-03-06 07:51:56.206 :: A: 10
2012-03-06 07:51:56.206 :: A: Leaving acquire()
2012-03-06 07:51:56.206 :: B: new value97

This time everything is fine. why so?

If there are many synchronized blocks on same object and any thread has entered into one of the synchronized block then no other thread can enter into any synchronized block on the same object. synchronized checks happens-before condition then either it acquire lock or waits until another thread releases lock or get interrupted.

synchronized blocks on different-2 objects has no interrelation. Any thread can enters into any synchronized block. Synchronized(a) and synchronized(this) are also non-related.
Lets play with some more code:

public void modify(int n){
	this.a=n;
	print("new value" + a);
}
public void display (int n){
	print("a=" + a);
	synchronized(a){
		try{
			Thread.sleep(1000);
			print("a=" + a);
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
}

Output:

a=34
new value45
a=45

Code Postmortem

Thread 1 inserts into synchronized block of display(). It takes lock on a. Thread 2 insert into modify(). But there is no new synchronized block. So it doesn’t check whether some thread has taken lock on a before. So it allows modification in a. Thus display() prints modified value of a.

If I makes modify() synchronized even, it doesn’t change the output.

public synchronized void modify(int n){
	this.a=n;
	print("new value" + a);
}

Because making modify() synchronized ensures that no more than 1 thread can call modify() at a time. It is not related to synchronized(a).

Lets read some more important points about synchronization.

If you are starting threads on 2 separate objects then there is no relation between those threads because both objects use different memory address. Hence their synchronized blocks are also not related.
synchronized(a) should not contain any statement modifying value of a. You’ll notice it when you’ll read about wait(),notify() etc. However it is allowed.

Synchronizing a method or using synchronized(this) everywhere in class is not good practice. Because it blocks all threads to access any synchronized block. Taking lock on necessary field is always a good practice.

Deadlock

I tried to code many programs which can help me to understand race condition, starvation, and deadlock practically. But I failed. Unknowingly I made this program which creates deadlock due improper synchronization.

public synchronized void acquire() throws Exception{
	Thread.sleep(5000);
	synchronized(lock){
		wait(1);
	}
}

public synchronized void modify() throws Exception{
	Thread.sleep(5000);
	synchronized(lock){
		wait(1);
	}
}

I added a tracer who explained me why both threads were getting blocked. You can integrate separate java thread tracer with your other threading programs.

Refer the output below to understand how improper nested monitoring took lock.

Output:

A:8
B:9
2012-03-07 19:54:57.625 :: [A:RUNNABLE,B:RUNNABLE]
2012-03-07 19:54:57.788 :: [A:RUNNABLE,B:BLOCKED]
2012-03-07 19:54:57.804 :: [A:TIMED_WAITING,B:BLOCKED]
2012-03-07 20:54:59.888 :: [A:RUNNABLE,B:BLOCKED]
2012-03-07 19:55:02.787 :: [A:TIMED_WAITING,B:TIMED_WAITING]
2012-03-07 19:55:02.788 :: [A:BLOCKED,B:TIMED_WAITING]
2012-03-07 19:55:07.787 :: [A:BLOCKED,B:RUNNABLE]
2012-03-07 19:55:07.787 :: [A:BLOCKED,B:BLOCKED]
Both threads are blocked
Deadlock detected in
Thread id: 9
Thread id: 8

Proper synchronization:

public void acquire() throws Exception{
	Thread.sleep(5000);
	synchronized(lock){
		lock.wait(1);
	}
}

public void modify() throws Exception{
	Thread.sleep(5000);
	synchronized(lock){
		lock.wait(1);
	}
}

You can solve this deadlock in another way as well. Its up to your need.

Categories: Java, Multithreading

Java Multithreading – Notify & Wait

January 20, 2016 Leave a comment

Read about synchronization first to understand this article better.

notify() or notifyAll(), and wait() must be in a synchronized block for the object you are waiting on. So the following codes are correct;

public synchronized void method(){
	wait(); //or this.wait();
}

public void method(){
	synchronized(this){
		wait(); //or this.wait();
	}
}

public void method(){
	synchronized(a){
		a.wait();
	}
}

public synchronized void method(){
	synchronized(a){
		wait();
	}
}

But following code generates run time exception java.lang.IllegalMonitorStateException

public void method(){
	synchronized(a){
		wait();
	}
}

public void method(){
	synchronized(a){
		synchronized(this){
			wait(n);
		}
	}
}

public synchronized void method(){
	synchronized(a){
		wait(n);
	}
}

If you change synchronized object inside synchronized block notify() or notifyAll(), and wait() will give run time exception java.lang.IllegalMonitorStateException.

synchronized(a){
	a = 55;
	a.wait();
}

In above example, you are waiting on new copy of a while synchronizing on old copy of a. Below code doesn’t generate exception.

synchronized(a){
	a.wait();
	a = 55;
}

Because you are waiting on same copy of a, you are synchronizing on. Then you are changing a.

Thread.sleep(1000) asks current thread to wait till specified period. It doesn’t bother about locks and all. So it doesn’t releases lock. On the other hand, wait() releases lock and acquires lock again once notify() or notifyAll() get called on same object or specified time is over.

public void acquire(){
	synchronized(a){
		print("acquire()");
		try{
			a.wait(5000);
			print("I have awoken");
			print(":" + a);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	print(&quot;Leaving acquire()&quot;);
}

public void modify(int n){
	print("Entered in modify");
	synchronized(a){
		try{
			a.wait(3000);
			this.a=n;
			print("new value " + a);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

Output:
2012-03-06 19:51:27.969 :: A: acquire()
2012-03-06 19:51:27.969 :: B: Entered in modify
2012-03-06 19:51:32.992 :: B: new value 97
2012-03-06 19:51:32.992 :: A: I have awoken
2012-03-06 19:51:32.992 :: A: 97
2012-03-06 19:51:32.992 :: A: Leaving acquire()

Explanation:

Thread A: enters into monitor of a.
Thread B: waits to get entered into monitor of a.
Thread A: meets to a.wait(5000). So it releases lock on a.
Thread B: enters into monitor a. waits and acquires lock on a.
Thread A: try to acquire released lock. But it is already acquired by Thread B. So it waits.
Thread B: changes value of a.
Thread A: acquire lock on a. It prints new value of a.
On the other hand, if I use Thread.sleep(n) in place of wait(n)

public void acquire(){
	synchronized(a){
		print("acquire()");
		try{
			//a.wait(5000);
			Thread.sleep(5000);
			print("I have awoken");
			print(":" + a);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	print("Leaving acquire()");
}

Output:
2012-03-06 20:02:39.395 :: A: acquire()
2012-03-06 20:02:39.395 :: B: Entered in modify
2012-03-06 20:02:44.418 :: A: I have awoken
2012-03-06 20:02:44.418 :: A: 10
2012-03-06 20:02:44.418 :: A: Leaving acquire()
2012-03-06 20:02:49.427 :: B: new value 97

Explanation:
When Thread A meets to sleep(n) it doesn’t release lock.

The problem with calling wait() and notify() on the empty string, or any other constant string is, that the JVM/Compiler internally translates constant strings into the same object. That means, that even if you have two different MyWaitNotify instances, they both reference the same empty string instance. This also means that threads calling wait() on the first MyWaitNotify instance risk being awakened by notify() calls on the second MyWaitNotify instance.
If there are multiple threads waiting on same object, notify() can awake any thread randomly. It arises the condition that some threads never get awaken and some always get awaken. This situation is called Starvation. Sometimes some greedy threads don’t release resources (call sleep() instead of wait() etc). It also force other threads to wait. Some threads increase their priority to get served first to CPU, it also force low priority threads to wait for long. These all conditions where any thread need to wait very long is called Starvation.

 

Categories: Multithreading
%d bloggers like this: