Java: Synchronization Utility

2020-06-24 01:42发布

I am asking this purely to determine the worthwhile-ness of implementing the class in Question ...

Do you know of a Java utility class that takes an un-synchronized instance, uses reflection to investigate that instance, and returns the input instance "wrapped" within synchronized calls ?

( ie: A factory which creates a synchronized delegate class for any instance )

4条回答
Evening l夕情丶
2楼-- · 2020-06-24 02:19

I like Jon Skeet's answer; it's seeing the forest instead of the trees. But to answer the question:

Assuming that the instance belongs to some interface, it's easy to use java.lang.reflect.Proxy to do this.

public final class SynchronizedFactory {
    private SynchronizedFactory() {}

    public static <T> T makeSynchronized(Class<T> ifCls, T object) {
        return ifCls.cast(Proxy.newProxyInstance(
                object.getClass().getClassLoader(),
                new Class<?>[] {ifCls},
                new Handler<T>(object)));
    }

    private static class Handler<T> implements InvocationHandler {
        private final T object;

        Handler(T object) {
            this.object = object;
        }

        @Override
        public Object invoke(Object proxy, Method method,
                Object[] args) throws Throwable {
            synchronized (object) {
                return method.invoke(object, args);
            }
        }
    }
}

This code is not tested, by the way. Use at your own risk.

查看更多
Bombasti
3楼-- · 2020-06-24 02:20

No, I don't know of anything which does that - and I'd rarely want to use it.

Synchronizing individual operations is rarely a useful feature. Typically you want to synchronize a few operations at a time. Something which simply synchronizes individual operations gives an illusion of thread-safety (enough to make some programmers careless) without dealing with the real decisions of which operations need to be performed in an atomic fashion for any particular situation.

查看更多
老娘就宠你
4楼-- · 2020-06-24 02:23

The overhead from reflection would also reduce the speedup that you'd get by threading your code...

查看更多
爷的心禁止访问
5楼-- · 2020-06-24 02:28

I want to call attention to just how cool the solution from Chris Jester-Young is. I've refactored it into a simple static function that I've been successfully using which I've included below. Thanks Chris!

/**
 * Utility that can take any object that implements a given interface and returns
 * a proxy that implements the same interface and synchronizes all calls that are
 * delegated to the given object. From Chris Jester-Young, http://about.me/cky
 * @param interfaceClass The interface to synchronize. Use MyInterface.class.
 * @param object The object to synchronize that implements the given interface class.
 * @return A synchronized proxy object that delegates to the given object.
 */
public static <T> T makeSynchronized(Class<T> interfaceClass, final T object) {
    return interfaceClass.cast(
        Proxy.newProxyInstance(
            object.getClass().getClassLoader(),
            new Class<?>[]{interfaceClass},
            new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    synchronized (object) {
                        return method.invoke(object, args);
                    }
                }
            }
        )
    );
}
查看更多
登录 后发表回答