web developer & system programmer

coder . cl

ramblings and thoughts on programming...


java mutexes

published: 14-12-2009 / updated: 14-12-2009
posted in: algorithms, c, development, java, programming, tips
by Daniel Molina Wegener

Java synchronization is usually made through the synchronized keyword. Synchronized allow users to create a mutex around certain variable, class or method, where a mutex allows concurrent access to it. By concurrent access we should understand access from multiple threads. If an operation is atomic, there one and only one process or thread executing it. Then, mutex based operations are atomic.

In Java, thread synchronization made using the synchronized keyword can create a heavy — with a high number of threads — overhead in two main cases, the first one is when it is used on classes and the second one when it is used in methods. Then we must think a way to create small locks, mainly if we are using design patterns like singletons.

/* BAD CASE 1, throws NullPointerException */
class BadMutexBaseClass {
	private static BadMutexBaseClass singletonInstance;
	public static BadMutexBaseClass getInstance(void) {
		synchronized (singletonInstance) {
			if (singletonInstance == null) {
				singletonInstance = new BadMutexBaseClass();
			}
			return singletonInstance;
		}
	}
}
/* BAD CASE 2, heavy overhead */
class BadMutexBaseClass {
	private static BadMutexBaseClass singletonInstance;
	public synchronized static BadMutexBaseClass getInstance(void) {
		if (singletonInstance == null) {
			singletonInstance = new BadMutexBaseClass();
		}
		return singletonInstance;
	}
}

Both cases are wrong, we must use mutex object, without touching the singleton member and allowing the program to access the singleton atomically. We can use a basic Object instance to create the proper mutex.

/* MUTEX BASED CASE */
class MutexBaseClass {
	private static Object mutex = new Object();
	private static MutexBaseClass singletonInstance;
	public static MutexBaseClass getInstance(void) {
		synchronized (mutex) { /* critical section */
			if (singletonInstance == null) {
				singletonInstance = new MutexBaseClass();
			}
			return singletonInstance;
		}
	}
}

By creating a dummy object, we can use it as mutex in our program. With a more low level perspective, this technique is similar to the one used with pthread_mutex_lock(P) techniques while we are programming with threads in C. An interesting point is the fact that non-blocking algorithms are faster than locking ones. The mutex technique is a blocking technique. Non-blocking techniques, such as lock-free and obstruction-free, can allow the user to implement faster — but more complex — code.

GCC has built-in atomic operations to allow the creation of such code, like CAS operations, allowing the use of lock-free techniques. For example in the code bellow — which is using the __sync_bool_compare_and_swap atomic operation — we can see that the CAS or Compare and Swap operation is made around the number of transactions with old value and old value plus one.

do {
	old = vproc_shmem->vp_shmem_transaction_cnt;

	if (unlikely(old < 0)) {
		if (vproc_shmem->vp_shmem_flags & VPROC_SHMEM_EXITING) {
			_exit(0);
		} else {
			__crashreporter_info__ = "Unbalanced: vproc_transaction_begin()";
		}
		abort();
	}
} while( !__sync_bool_compare_and_swap(&vproc_shmem->vp_shmem_transaction_cnt, old, old + 1) );

I hope that Java will include kind that atomic operations to allow the use of non-blocking algorithms and more faster code and since I agree with the fact that we are entering the multi-core era…


No coments yet.

post a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>