【问题标题】:Is java.lang.reflect.Method thread safe?java.lang.reflect.Method 线程安全吗?
【发布时间】:2011-03-18 07:59:01
【问题描述】:

java.lang.reflect.Method 线程安全吗?

我的程序的分析结果表明,Class.getMethod() 在多次调用时花费了相当多的计算时间,比我预期的要多一点。 我可以调用一次并将生成的方法存储在易于访问的地方。 但随后,多个 Web Worker 线程将同时使用存储的 Method 对象。

这样安全吗?

【问题讨论】:

    标签: java


    【解决方案1】:

    该方法可以安全地跨多个线程使用,前提是您在使方法可用于多个线程后不更改该方法的状态。例如您可以在两个线程中调用 setAccessible(true) 和 setAccessible(false),结果将不是线程安全的。但是,这并没有真正的用处。

    简而言之,Method.setAccessible() 在技术上不是线程安全的,但您应该能够以线程安全的方式使用它。

    【讨论】:

    • 顺便问一下,setAccessible 不是安全漏洞吗?如果某些代码有权设置可访问的内容,那么稍后另一个代码可以使用私有方法而无需更多安全检查。
    • 除非您的 SecurityManager 阻止它,否则您可以访问受保护的、打包的本地和私有方法。它通过覆盖检查提高了甚至公共方法的访问性能。
    • 是的,我说的是安装了安全管理器的案例......以及不同代码部分的不同权限。但我最好就此提出另一个问题,而不是使用 cmets 来解决一个不相关的问题。
    • 啊,刚刚做了一些实验:实际上每个方法(或字段/构造函数)对象都有自己的可访问状态,并且每次调用getMethod() 等时都会得到一个新的。所以只要你不与不受信任的代码共享这个对象(或者给这个不受信任的代码一个新的不可访问的副本),你就很好。
    【解决方案2】:

    Java 类保证每个 ClassLoader 实例只定义一次,因此您可以放心地假设定义(包括方法及其签名)不会随时间而改变,因此您可以安全地“缓存”它们以供多个线程使用。

    但是,请记住,具有相同完全限定名(包 + 类名)的类可以由不同的 ClassLoader 实例以不同方式定义。

    【讨论】:

      【解决方案3】:

      类定义不会改变,所以除非你在不同的线程中加载不同的类(比如从不同的库中),否则 Method 对象应该是线程安全的。 (当然,被反射调用的方法本身是否是线程安全的则是另外一个问题。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-15
        • 2011-07-04
        • 2014-04-26
        • 2012-11-30
        • 2010-12-30
        • 2013-03-12
        • 2021-08-03
        • 2010-12-27
        相关资源
        最近更新 更多