【问题标题】:Are Java arrays in a static method thread safe?静态方法线程中的Java数组是否安全?
【发布时间】:2011-11-04 21:13:45
【问题描述】:
   public static int rank(int key, int[] a) {
        int lo = 0;
        int hi = a.length - 1;
        while (lo <= hi) {
            // Key is in a[lo..hi] or not present.
            int mid = lo + (hi - lo) / 2;
            if      (key < a[mid]) hi = mid - 1;
            else if (key > a[mid]) lo = mid + 1;
            else return mid;
        }
        return -1;
    }

上述静态方法进行二分查找。它是线程安全的吗?我知道局部变量是线程安全的,但这里的“a”是一个数组,所以这意味着它是 Java 中的一个对象,对吧?那是问题吗? 数组只是被读取,没有以任何方式修改,所以我假设这个方法是线程安全的。但我想确保我明白为什么。

谢谢!

【问题讨论】:

    标签: java thread-safety static-methods


    【解决方案1】:

    没有数组通常不是线程安全的。你的代码是否在这种情况下,取决于其他线程是否可以访问你传入的数组。因为数组是通过引用传递的,所以其他线程可以访问它们。

    如果你只在一个线程中创建/修改数组,或者如果你传入一个以线程安全方式复制的副本,那就没问题了。

    【讨论】:

    • 我明白了。所以即使数组没有被修改,代码也不是线程安全的,对吧?但是只要调用这个方法的每个线程都用不同的数组对象来做这件事,生活就是美好的。
    • 顺便说一句-我认为说数组通过引用传递是不正确的(但我明白你的意思)。更准确地说,数组引用是按值传递的。谢谢!
    • 只是因为其他线程可能会在您阅读它的同时对其进行修改。
    • 谢谢@trinithis。我想我现在明白了。
    【解决方案2】:

    该方法本身是线程安全的,因为它只接受它的参数并读取它们,而不会将它们发布到任何其他线程。但这并不意味着您不会遇到线程问题。这一切都取决于论点来自哪里。

    如果参数构成线程之间的共享状态,那么每次对该状态的访问都应该以某种方式同步。但是你必须在线程之间建立一个同步策略来保护对这个状态的访问。所以这个方法,或者这个方法的调用者,应该确保对状态的访问是线程安全的。在不知道参数来自哪里的情况下,无法判断这段代码是否是线程安全的。

    【讨论】:

      【解决方案3】:

      是的,它是线程安全的,正如你所说的你只读取数组,唯一可能的问题是如果另一个线程在此方法读取数组的同时更新数组

      【讨论】:

      • 另一个线程仍然可以同时编辑数组的一项。
      • 最初不在您的答案中,您稍后在 5 分钟的宽限期内对其进行了编辑。
      猜你喜欢
      • 1970-01-01
      • 2018-01-17
      • 1970-01-01
      • 2018-10-23
      • 1970-01-01
      • 1970-01-01
      • 2014-09-16
      • 2010-11-08
      相关资源
      最近更新 更多