Java:同步实用程序

发布于 2024-07-16 19:25:16 字数 135 浏览 12 评论 0原文

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

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

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

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 )

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

可是我不能没有你 2024-07-23 19:25:16

我喜欢乔恩·斯基特的回答; 它只见树木而不见森林。 但要回答这个问题:

假设实例属于某个接口,那么使用 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);
            }
        }
    }
}

顺便说一下,这段代码没有经过测试。 使用风险自负。

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.

冷…雨湿花 2024-07-23 19:25:16

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

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

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.

近箐 2024-07-23 19:25:16

我想提醒大家注意 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);
                    }
                }
            }
        )
    );
}

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);
                    }
                }
            }
        )
    );
}
隔岸观火 2024-07-23 19:25:16

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文