【问题标题】:Are method parameters thread safe in Java?Java中的方法参数是线程安全的吗?
【发布时间】:2013-09-04 01:15:51
【问题描述】:
Class Shared{    
     public void sharedMethod(Object o){
          //does something to Object
     }     
}

//this is how threads call the shared method
run(){
     sharedInstance.sharedMethod(someObject);
}

现在o 作为参数传递给方法。多个线程并行调用相同的方法。我们可以肯定地说这段代码是线程安全的吗?

有两种情况:

  • 如果someObject 正在线程之间共享
  • 如果每个线程都有自己的someObject 副本

【问题讨论】:

  • 不,你不能这么说。

标签: java multithreading thread-safety method-parameters


【解决方案1】:

不,你不能这么说。方法参数是线程本地的,这意味着每个人都有自己的 o 引用变量的副本,但是如果您从多个线程中使用同一个对象调用此方法,那么参数将在它们之间共享(记住 Java 是通过——按价值)。在这种情况下,您需要提供显式同步以避免麻烦。

【讨论】:

  • 您有 2 个不同的“引用”副本(一个在调用方法中,一个在被调用方法中 - 因为按值传递),而不是“对象”本身。在一种方法中更改“引用”不会影响另一种方法(例如,被调用方法中的o=null 不会使调用方法中的o 无效),但更改它们引用的“对象”(在这种情况下,两者都引用对同一个对象)对另一个可见。因此,两个线程都在同一个对象上工作,因此不是线程安全的。
【解决方案2】:

是的,但仅限于两种情况

  • 如果您在o 参数中传递的每个对象都是不可变的
  • 如果您的代码保证最多有一个线程在处理o 引用的对象。

否则 - ,因为对象的内部状态可以由多个线程同时更改。

【讨论】:

    【解决方案3】:

    当您创建一个线程时,它会创建自己的堆栈(方法和局部变量)。

    两个线程将有两个堆栈,一个线程永远不会与任何其他线程共享其堆栈。

    直到你在同一个对象上调用它才会生效。

    【讨论】:

    • @Narenda 正在谈论对象参数(通过引用传递),所以它不是线程安全的。
    【解决方案4】:

    如果你在多个线程中调用同一个方法,并传递同一个对象,那么这个对象绝对是安全的。

    【讨论】:

      【解决方案5】:

      这样对待。

      如果您的线程不共享任何公共资源,那么就不可能出现并发问题。 从您提供的信息中我们可以看出,这里唯一可以分享的是someObject。如果它本身是线程安全的,或者为每个线程复制,那么您的代码通常是线程安全的,除非有其他共享资源。

      【讨论】:

        【解决方案6】:

        局部变量存储在每个线程自己的堆栈中。这意味着局部变量永远不会在线程之间共享。这也意味着所有局部原始变量都是线程安全的。

        编辑

        此示例中的 LocalObject 实例不是从方法返回的,也不会传递给可从sharedMethod() 方法外部访问的任何其他对象。

        每个执行sharedMethod() 方法的线程都会使用自己的对象o 作为参数。

        所以,整个方法sharedMethod() 似乎是线程安全的。

        当然,唯一的例外是,如果以 Object o 作为参数调用的方法之一,以允许从其他线程访问它的方式存储 Object o 实例。

        【讨论】:

          猜你喜欢
          • 2018-10-23
          • 1970-01-01
          • 2012-02-08
          • 2013-06-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-21
          • 1970-01-01
          相关资源
          最近更新 更多