How to avoid deadlock in Java Threads

Today’s post is on breaking Deadlock of multiple Threads : on “November 5, 2014” I had posted a code of creating Deadlock.
Today I am modifying the same code for avoiding such Deadlock. There are many ways to avoid a deadlock but simple rule is: have all threads claim and release their locks in the same order. In this way, you never get into a situation where a deadlock can occur.

My updated code without Deadlock
========================================

public class CustomerUpdateDeadloackThread {

	public static void main(String[] args) {

		Customer cstmr = new Customer("Peter");
		Address adrs = new Address("B-232, Bangalore");

		for (int i = 0; i < 10; i++) {
			new Thread(new TagObjectsToEachOther(cstmr, adrs)).start();
			new Thread(new TagObjectsToEachOther(adrs, cstmr)).start();
		}

	}
}

interface CustomerUpdater {

	public boolean update(Object obj);

}

class TagObjectsToEachOther implements Runnable {
	CustomerUpdater taskItem;
	Object objToUpdateWith;

	public TagObjectsToEachOther(CustomerUpdater cspdtr, Object obj2) {
		this.taskItem = cspdtr;
		this.objToUpdateWith = obj2;
	}

	@Override
	public void run() {
		taskItem.update(objToUpdateWith);
		System.out.println(" Task done :" + Thread.currentThread().getName());
	}

}

class Address implements CustomerUpdater {

	String address;
	Customer customer;

	public Address(String addrs) {
		this.address = addrs;
	}

	@Override
	public boolean update(Object cstmr) {

		synchronized ((Customer) cstmr) { // same order of locks will be used at other places !!!
			synchronized (this) {
				try {
					this.customer = (Customer) cstmr;
					Thread.sleep(2000); // or else do some other work here so that lock gets used for some more time
				} catch (CustomerUpdateFailureException e) {
					e.getCause();
					return false;
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return true;
			}
		}
	}

}

class Customer implements CustomerUpdater {

	String name;
	Address address;

	public Customer(String nm) {
		this.name = nm;
	}

	@Override
	public boolean update(Object adrs) {
		synchronized (this) {
			synchronized ((Address) adrs) { // Maintaining order of accessing lock to avoid deadlock !!!
				try {
					this.address = (Address) adrs;
					Thread.sleep(2000); // or else do some other work here so that lock gets used for some more time
				} catch (CustomerUpdateFailureException e) {
					e.getCause();
					return false;
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return true;
			}
		}
	}

}

class CustomerUpdateFailureException extends RuntimeException {

	private static final long serialVersionUID = 1L;

	@Override
	public String getMessage() {

		return "Uncompitable update";
	}

}

===================  Output =========================

 Task done :Thread-0
 Task done :Thread-9
 Task done :Thread-8
 Task done :Thread-7
 Task done :Thread-6
 Task done :Thread-5
 Task done :Thread-4
 Task done :Thread-3
 Task done :Thread-2
 Task done :Thread-1

use Weak reference for high availability of cache and In-Memory DB operations

We should think about usingĀ WeakReference whenever we need a reference to an object, but you don’t want that reference to protect the object from the garbage collector. A classic example is a cache that we want to be garbage collected when memory usage gets too high.

Basically a WeakReference will be GC-d by the JVM eagerly, once the referenced object has no hard references to it. A SoftReferenced object on the other hand, will tend to be left about by the garbage collector until it really needs to reclaim the memory.

Suppose there is a Query level cache and it is persisted and attached to a session. If such queries are very high, certainly they will occupy a huge memory and then they need to be claimed ( GC-d ) as soon as not required. For this, Class Query should be implemented or enqueued through WeakReference.