3

我问这个纯粹是为了确定在问题中实现类的价值......

您是否知道一个 Java 实用程序类,它采用非同步实例,使用反射来调查该实例,并在同步调用中返回“包装”的输入实例?

(即:为任何实例创建同步委托类的工厂)

4

4 回答 4

8

不,我不知道有什么能做到这一点——而且我很少想使用它。

同步单个操作很少是有用的功能。通常,您希望一次同步几个操作。简单地同步单个操作的东西给人一种线程安全的错觉(足以让一些程序员粗心),而没有处理在任何特定情况下需要以原子方式执行哪些操作的真正决定。

于 2009-04-13T07:53:56.660 回答
7

我喜欢 Jon Skeet 的回答;它看到的是森林而不是树木。但是要回答这个问题:

假设实例属于某个接口,使用起来很容易java.lang.reflect.Proxy

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

顺便说一句,此代码未经测试。使用风险自负。

于 2009-04-13T08:01:22.307 回答
1

我想提请注意 Chris Jester-Young 的解决方案有多酷。我已将它重构为一个简单的静态函数,我已成功使用该函数,我已将其包含在下面。谢谢克里斯!

/**
 * 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);
                    }
                }
            }
        )
    );
}
于 2014-01-20T20:35:14.920 回答
-1

反射的开销也会降低通过线程化代码获得的加速......

于 2009-04-28T06:23:02.463 回答