【发布时间】:2011-03-18 07:59:01
【问题描述】:
java.lang.reflect.Method 线程安全吗?
我的程序的分析结果表明,Class.getMethod() 在多次调用时花费了相当多的计算时间,比我预期的要多一点。
我可以调用一次并将生成的方法存储在易于访问的地方。
但随后,多个 Web Worker 线程将同时使用存储的 Method 对象。
这样安全吗?
【问题讨论】:
标签: java
java.lang.reflect.Method 线程安全吗?
我的程序的分析结果表明,Class.getMethod() 在多次调用时花费了相当多的计算时间,比我预期的要多一点。
我可以调用一次并将生成的方法存储在易于访问的地方。
但随后,多个 Web Worker 线程将同时使用存储的 Method 对象。
这样安全吗?
【问题讨论】:
标签: java
该方法可以安全地跨多个线程使用,前提是您在使方法可用于多个线程后不更改该方法的状态。例如您可以在两个线程中调用 setAccessible(true) 和 setAccessible(false),结果将不是线程安全的。但是,这并没有真正的用处。
简而言之,Method.setAccessible() 在技术上不是线程安全的,但您应该能够以线程安全的方式使用它。
【讨论】:
setAccessible 不是安全漏洞吗?如果某些代码有权设置可访问的内容,那么稍后另一个代码可以使用私有方法而无需更多安全检查。
getMethod() 等时都会得到一个新的。所以只要你不与不受信任的代码共享这个对象(或者给这个不受信任的代码一个新的不可访问的副本),你就很好。
Java 类保证每个 ClassLoader 实例只定义一次,因此您可以放心地假设定义(包括方法及其签名)不会随时间而改变,因此您可以安全地“缓存”它们以供多个线程使用。
但是,请记住,具有相同完全限定名(包 + 类名)的类可以由不同的 ClassLoader 实例以不同方式定义。
【讨论】:
类定义不会改变,所以除非你在不同的线程中加载不同的类(比如从不同的库中),否则 Method 对象应该是线程安全的。 (当然,被反射调用的方法本身是否是线程安全的则是另外一个问题。)
【讨论】: