[concurrency-interest] thread queueing qn

Gregg Wonderly gregg at cytetech.com
Mon Jan 21 15:49:04 EST 2008

Dhanji R. Prasanna wrote:
> On 1/19/08, *Rémi Forax* <forax at univ-mlv.fr <mailto:forax at univ-mlv.fr>> 
> wrote:
>     Dhanji R. Prasanna a écrit :
>      > - as an alternative, I don't want to force/trust users to expose a
>      > locking API
>     and it can don't work at all because lot of persistence storages use
>     equals() semantics (two persistent objects are equals using equals())
>     and synchronized use == semantic.
> Oh that's a very important point! Thank you, Remi =)

ConcurrentHashTable and Futures can often help in these kinds of situations. 
You can use the equals() semantics to pick a unique entry in a map (the Future) 
to use for locking.  Here's something that I hope conveys what I mean.  I'm 
coding this on the fly...

ConcurrentHashMap<KeyValue,Future> map =
	new ConcurrentHashMap<KeyValue,Future>();

public Object doWorkFor( KeyValue key, Runnable work ) {
	Object o = null;
	do {
		// Wrap the runnable for execution
		Future f = new FutureTask<Void>( work );

		// Try to reserve the right to work on "key"
		Future nf = map.putIfAbsent( key, f );

		if( nf != null ) {
			// Someone already working, wait for other
			// user to finish
			// There is another thread that needs to remove
			// their future from the map, yield to that
			// activity.
		} else {
			try {
				// We got in, run our work
				o = f.run();
			} finally {
				// Remove our key.  There might be some
				// spinning of other threads between the
				// time that the future is valid and the
				// key is removed.
				map.remove( key );
	} while( nf != null );

	// Return the result of our work.
	return o;

The equals()/hashcode() semantics select the lock to use.  There is no thread 
pool, so you see synchronous execution which provides automatic throttling.

Gregg Wonderly

More information about the Concurrency-interest mailing list