java.lang.Class方法是否安全? [英] Are java.lang.Class methods thread safe?

查看:102
本文介绍了java.lang.Class方法是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在IBM JVM下,当多个线程试图在不同对象上同时调用Class.getAnnotation时(但具有相同的注释),我们遇到了一个问题。线程开始在Hashtable内的监视器上等待死锁,Hashtable用作IBM JVM中注释的缓存。最奇怪的是,持有此监视器的线程在Hashtable.get内部进入等待状态状态,使所有其他线程无限期地等待。

Under IBM JVM we have faced an issue when multiple threads are trying to call Class.getAnnotation at the same time on different objects (but with the same annotation). Threads are starting to deadlock waiting on a monitor inside a Hashtable, which is used as a cache for annotations in IBM JVM. The weirdest thing is that the thread that is holding this monitor is put into 'waiting on condition' state right inside Hashtable.get, making all other threads to wait indefinitely.

IBM的支持表示,Class.getAnnotation的实现不是线程安全的。

The support from IBM stated, that implementation of Class.getAnnotation is not thread safe.

与其他JVM实现(例如,OpenJDK)相比,我们看到他们实现了Class方法以线程安全的方式。 IBM JVM是一个封闭的源JVM,它们确实发布了一些源代码和它们的JVM,但是只要它们的Class实现是否是线程安全的,它就不足以做出明确的判断。

Comparing to other JVM implementations (for example, OpenJDK) we see that they implement Class methods in thread safe manner. IBM JVM is a closed source JVM, they do publish some source code together with their JVM, but it's not enough to make a clear judgment whenever their implementation of Class is thread safe or not.

只要其方法是线程安全的,Class文档就不会明确说明。因此,将类方法(特别是getAnnotation)视为线程安全或者必须在多线程环境中使用同步块是一种安全的假设吗?

The Class documentation doesn't clearly state whenever its methods are thread safe or not. So is it a safe assumption to treat Class methods (getAnnotation in particular) as a thread safe or we must use sync blocks in multi threaded environment?

流行框架如何(例如,Hibernate)正在缓解这个问题吗?我们在使用getAnnotation方法的Hibernate代码中没有发现任何同步用法。

How do popular frameworks (ex. Hibernate) are mitigating this problem? We haven't found any usage of synchronization in Hibernate code that was using getAnnotation method.

推荐答案

好吧,没有指定的行为,所以通常处理它的正确方法是说如果没有指定行为,则假设没有安全保证。

Well, there is no specified behavior, so normally the correct way to deal with it would be to say "if no behavior is specified, assume no safety guarantees".

但是...

这里的问题是如果这些方法不是线程安全的,那么规范缺少如何正确实现线程安全的文档。回想一下,如果您的JVM托管多个apps / applets / servlets / beans / etc,那么整个应用程序的所有线程甚至在多个应用程序中都可以看到 java.lang.Class 的实例。 。

The problem here is that if these methods are not thread-safe, the specification lacks a documentation of how to achieve thread-safety correctly here. Recall that instances of java.lang.Class are visible across all threads of the entire application or even within multiple applications if your JVM hosts multiple apps/applets/servlets/beans/etc.

因此,与您自己实例化的类不同,您可以控制对这些实例的访问,您不能阻止其他线程访问特定方法的相同方法 java.lang.Class 实例。因此,即使我们参与非常尴尬的概念,依赖某种约定来访问这样的全局资源(例如说调用者必须做 synchronized(x.class)),这里的问题是,甚至更大,没有这样的约定存在(好的,或者没有记录下来的相同)。

So unlike classes you instantiate for your own use where you can control access to these instances, you can’t preclude other threads from accessing the same methods of a particular java.lang.Class instance. So even if we engage with the very awkward concept of relying on some kind of convention for accessing such a global resource (e.g. like saying "the caller has to do synchronized(x.class)"), the problem here is, even bigger, that no such convention exists (well, or isn’t documented which comes down to the same).

所以在这种特殊情况下,没有记录调用者的责任,如果没有这样的文档就无法建立,IBM负责告诉他们如何思考,程序员应该使用这些方法是以非线程安全的方式实现的。

So in this special case, where no caller’s responsibility is documented and can’t be established without such a documentation, IBM is in charge of telling how they think, programmers should use these methods correctly when they are implemented in a non-thread-safe manner.

我想要添加另一种解释:所有信息, java.lang.Class offer,具有静态常量性质。这个类反映了总是被编译到课堂中的东西。它没有改变任何状态的方法。所以也许没有额外的线程安全文档,因为所有信息都被认为是 immutable ,因此自然是线程安全的。

There is an alternative interpretation I want to add: all information, java.lang.Class offers, is of a static constant nature. This class reflects what has been invariably compiled into the class. And it has no methods to alter any state. So maybe there’s no additional thread-safety documentation as all information is to be considered immutable and hence naturally thread-safe.

相反,事实上根据需要加载一些信息是程序员不需要注意的未记录的实现细节。因此,如果JRE开发人员决定实现延迟创建以提高效率,他们必须维护类似不可变行为,读取线程安全。

Rather, the fact that under the hood some information is loaded on demand is the undocumented implementation detail that the programmer does not need to be aware of. So if JRE developers decide to implement lazy creation for efficiency they must maintain the like-immutable behavior, read thread safety.

这篇关于java.lang.Class方法是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆