【问题标题】:Java thread safe recursionJava线程安全递归
【发布时间】:2011-11-23 20:37:43
【问题描述】:

我有嵌套类 CRecursion,它有递归的方法。 此 CRecursion 在许多线程中创建。从主类的线程方法安全调用吗? 谢谢。

class A {
method1() {....}

for(int i=0;i<100;i++){
   execute(new CRecursion(...))
 }

protected CRecursion {

calculate (par){
  if (some_condition) {
     calculate(par1)
 } else {
  String s=method1(value);
  .....
 }

}
....
}

变量值是对象。但是对于每种方法都是内部的。

【问题讨论】:

  • 不同的调用是否共享相同的可变数据?还是他们都在处理方法本身的本地数据?
  • 如果您有一个 CPU 密集型进程,那么要使用的最佳线程数很可能是您拥有的内核数。例如如果您有 4 个内核,则仅使用 4 个线程。这可以帮助您确定这是否是一个好主意。 ;)
  • 此外,在函数式语言中使用递归最好表示的内容通常最好在 Java 中作为循环执行。即更快。在某些情况下递归最快,但在 Java 中这种情况比较少见。

标签: java multithreading recursion


【解决方案1】:

我们需要有关您的计算方法的更多详细信息来回答您的问题。如果您只使用局部范围的变量(即,您在方法中创建的变量/数据),那么您就可以了。

如果您正在访问类中的数据,但只读取该数据,那么您就可以了。

如果您正在访问类中的数据,并且正在写入该数据,那么您可能会遇到问题。这就是关键字 synchronized 的用途...您可以同步一个/多个代码块,以便在任何给定时间只能执行一个块。当然,这通常需要权衡速度。

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    如果递归例程使用的对象被限制在同一个线程中,那么是的,递归例程是线程安全的。阅读this related StackOverflow question on thread confinement and it's impact on thread-safety 会有所帮助。

    在这种特殊情况下(使用您发布的代码),您需要确保:

    • CRecursion 的构造函数的参数不能在多个线程之间共享。如果它们是共享的,那么以下几点变得相关。
    • 在递归例程中不得访问(读取或写入)跨多个线程共享的任何对象。
    • 递归例程使用局限于当前堆栈帧的局部变量。该例程不得访问任何其他共享存储区域(Java 调用堆栈除外)以在调用之间交换数据。

    【讨论】:

      【解决方案3】:
      1. 您是否在线程之间共享任何数据?

      如果对上述问题的回答是否定的,那么调用是隐式线程安全的。

      如果你担心不同线程多次调用同一个方法会导致局部变量出现乱码,那你就错了。方法的每次调用都会创建自己的这些变量的单独副本。

      本质上,如果您不共享任何数据,则您的调用是线程安全的。

      从技术上讲,您仍然可以共享数据并且是线程安全的,唯一的条件是对共享数据的所有访问都必须是读取操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-06-06
        • 2012-02-25
        • 1970-01-01
        • 2021-12-16
        • 2010-11-14
        • 2014-09-16
        • 2010-10-12
        相关资源
        最近更新 更多