Java: Synchronization Utility

淺唱寂寞╮ 提交于 2019-12-05 02:53:14

问题


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 )


回答1:


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.




回答2:


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.




回答3:


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);
                    }
                }
            }
        )
    );
}



回答4:


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



来源:https://stackoverflow.com/questions/743288/java-synchronization-utility

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!