【问题标题】:When do you have to worry about thread safety?什么时候需要担心线程安全?
【发布时间】:2010-12-14 22:46:23
【问题描述】:

在哪些情况下您需要担心静态方法是否是线程安全的?

例如,如果我有一个不涉及任何静态类级别变量的静态实用程序函数,那么该方法是否已经是线程安全的?如果我有一个接触静态类变量的静态方法,该方法是否可能不是线程安全的?

提前致谢。

【问题讨论】:

    标签: java multithreading thread-safety


    【解决方案1】:

    如果我有不涉及任何静态类级别变量的静态实用程序函数,那么该方法是否已经是线程安全的?

    大多数时候 - 重要的是您的方法是否是 reentrant。像这样的东西是可重入的,因为一切都是局部变量,每个线程都会收到自己的副本:

    static int add(int a, int b)
    {
        return a + b;
    }
    

    还有一些事情需要注意。如果您将一个对象传递给该方法并且该方法改变了该对象,并且在该方法完成之前您在不同的线程上再次调用相同的方法但使用相同的对象,那么您就有问题了。

    如果我有一个接触静态类变量的静态方法,该方法是否可能不是线程安全的?

    主要问题还是变量是否可变。如果您只是从不可变对象中读取,那么可能没有任何问题。

    如果你调用一个方法并且你不确定它是否是可重入的并且文档没有说明,最好假设它不是。

    【讨论】:

    • 考虑 同时 读/写是不够的;如果内存没有围绕屏障同步(如 JMM 所记录的那样),则一个或其他线程可以观察到陈旧的值,并且写入的值可能会丢失,即使它们实际上没有及时冲突。出于同样的原因,即使没有某种内存屏障,即使只有一个编写器线程场景也会被破坏。
    【解决方案2】:

    如果您在静态方法中仅使用局部堆栈变量,则无需担心。 java.lang.Math.min(int, int) 就是这种方法的一个很好的例子。但是如果你接触到任何共享的静态变量,或者有状态的对象(也就是不可变的),那么你必须使用同步。

    【讨论】:

    • 你的意思是在你的第一句话中'没有理由担心'......?
    • 谢谢托尼。那是一个错字。
    • "aka not immutable" 简称为 "aka mutable" ))
    【解决方案3】:

    当您有多个线程访问同一资源时,您必须担心线程安全。

    如果静态方法使用与其他线程相同的资源(直接或间接),即使这些资源不是静态类变量,它也可能不安全。

    【讨论】:

    • 还有两个线程共享数据的静态字段以外的方法。考虑方法 static void MyClass.copy(to, from )。
    【解决方案4】:

    如果不访问可变资源(例如类变量),则它是线程安全的 - 但是,您必须确保您的方法不会调用任何其他访问任何可变资源的方法。

    【讨论】:

    • 但是,如果访问是同步的,即使访问可变资源,它也可能是线程安全的。
    【解决方案5】:

    当您有多个线程访问同一资源时,您必须担心线程安全,并且这些资源不是不可变的。

    【讨论】:

    • 为什么大家都在使用“not immutable”而不是“mutable”
    【解决方案6】:

    如果您有一个方法可以写入在多个线程之间共享的任何状态(例如,静态变量或多个线程使用的任何对象),那么该方法需要担心线程-安全性,读取任何共享状态的任何方法也是如此。

    【讨论】:

      【解决方案7】:

      如果至少有一个入口点可以被多个线程访问,那么线程安全就会成为一个问题。

      如果一段代码被多个线程访问并正在调用其他方法/类/等,那么所有代码​​树都会变得容易受到攻击。

      来自“Java 并发实践”: 围绕任务执行组织程序的第一步是确定合理的任务边界。理想情况下,任务是独立的活动:不 取决于其他任务的状态、结果或副作用。独立性有助于并发性,因为如果有独立的任务可以并行执行 足够的处理资源。

      例如,如果您正在编写一个隔离的 servlet,它保证由单个线程执行,您不必担心。但是如果你编写一个静态实用程序供不同的 servlet 使用,那么它必须能够处理多线程访问。

      【讨论】:

        猜你喜欢
        • 2017-01-05
        • 1970-01-01
        • 2011-01-13
        • 1970-01-01
        • 2011-09-22
        • 1970-01-01
        • 2011-05-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多