[concurrency-interest] Concurrency Wrappers

Daniel Yokomiso daniel_yokomiso@yahoo.com.br
Wed, 25 Jun 2003 13:11:13 -0300


----- Original Message -----
From: "Curt at Tripos" <ccox@tripos.com>
To: <concurrency-interest@altair.cs.oswego.edu>
Sent: Wednesday, June 25, 2003 11:43 AM
Subject: [concurrency-interest] Concurrency Wrappers


> Hi All,
>
> The java.util.* collections have some concurrency support.
> The collection implementations are unsynchronized.
> Synchronization and protection against modification can
> be added via several provided wrapper methods located in
> java.util.Collections.
>
> Collection synchronizedCollection(Collection c)
> List       synchronizedList(List list)
> Map        synchronizedMap(Map m)
> Set        synchronizedSet(Set s)
> SortedMap  synchronizedSortedMap(SortedMap m)
> SortedSet  synchronizedSortedSet(SortedSet s)
> Collection unmodifiableCollection(Collection c)
> List       unmodifiableList(List list)
> Map        unmodifiableMap(Map m)
> Set        unmodifiableSet(Set s)
> SortedMap  unmodifiableSortedMap(SortedMap m)
> SortedSet  unmodifiableSortedSet(SortedSet s)
>
> This pattern
> (interface + unsynchronized implementations + concurrency wrappers)
> seems to work pretty well.  It allows testing different solutions
> to concurrency problems by simply changing wrappers.
>
> Given all of the new concurrency options about to be introduced,
> I would welcome a factory class that generated an assortment of
> concurrency wrappers.  I propose adding a wrapper class with at
> least the following methods.   The goal is to make the most common
> usage as simple as possible.
>
> /**
> Returns a synchronized (thread-safe) object backed
> by the specified object.  The object returned implements the
> same interfaces as the given object.
> */
> public static Object synchronizedObject(Object object);
>
> /**
> Returns an object that is locked with the given lock and backed
> by the specified object.  The object returned implements the
> same interfaces as the given object.
> */
> public static Object lockedObject(Lock lock, Object object);
>
> Thanks,
> Curt

Hi,

    As it is very easy to do something similar using dynamic proxies (i.e.
regarding a known set of interfaces), I don't think it should be part of
this library. Otherwise it's very difficult to know how to implement such
methods using plain Java, because if you don't know the exact interfaces,
you can't easily (i.e. without heavy reflection usage + byte-code
generation) define the appropriate proxies. In the collections case the
interfaces are known at compile-time, so it isn't a problem.
    I'm also posting a pure Java solution to this, using dynamic proxies.

    Best regards,
    Daniel Yokomiso.

"Common sense is that layer of prejudices which we acquire before we are
sixteen."
 - Albert Einstein



/*
Originally written by Daniel Yokomiso and released into the public domain.
This may be used for any purposes whatsoever without acknowledgment.
*/

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.concurrent.Lock;

public class SynchronizationHelper {
    private SynchronizationHelper() {
    }
    public static Object synchronizedObject(Class[] interfaceClasses, Object
wrapped) {
        return create(interfaceClasses, new SynchronizingProxy(wrapped));
    }

    public static Object synchronizedObject(Class interfaceClass, Object
wrapped) {
        return create(interfaceClass, new SynchronizingProxy(wrapped));
    }
    public static Object lockedObject(Class[] interfaceClasses, Lock lock,
Object wrapped) {
        return create(interfaceClasses, new LockingProxy(lock, wrapped));
    }
    public static Object lockedObject(Class interfaceClass, Lock lock,
Object wrapped) {
        return create(interfaceClass, new LockingProxy(lock, wrapped));
    }
    private static Object create(Class interfaceClass, InvocationHandler
handler) {
        return create(new Class[] { interfaceClass }, handler);
    }
    private static Object create(Class[] interfaceClasses, InvocationHandler
handler) {
        return Proxy.newProxyInstance(
            interfaceClasses[0].getClassLoader(),
            interfaceClasses,
            handler);
    }
}
public class SynchronizingProxy implements InvocationHandler {
    private final Object wrapped;
    public SynchronizingProxy(Object wrapped) {
        this.wrapped = wrapped;
    }
    public synchronized Object invoke(Object proxy, Method method, Object[]
args)
        throws Throwable {
        return method.invoke(wrapped, args);
    }
}

public class LockingProxy implements InvocationHandler {
    private final Lock lock;
    private final Object wrapped;
    public LockingProxy(Lock lock, Object wrapped) {
        this.lock = lock;
        this.wrapped = wrapped;
    }
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {
        lock.lock();
        try {
            return method.invoke(wrapped, args);
        } finally {
            lock.unlock();
        }
    }
}


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.491 / Virus Database: 290 - Release Date: 18/6/2003