静态内部类线程在另一个java类中是否安全?

时间:2011-06-24 04:00:15

标签: java static thread-safety inner-classes

为了收集较小的辅助工具类,我创建了一个通用class MyUtils

// MyUtils.java
public final class MyUtils
{
  public static class Helper1 {};
  public static class Helper2 {};
//...
}

来自MyUtils内部的帮助程序类将用于程序包的其他文件中:

// MyClass1.java
public class MyClass1
{
  private MyUtils.Helper1 help1 = new MyUtils.Helper1();
  public void method ()
  {
    private MyUtils.Helper2 help2 = new MyUtils.Helper2();
  }
}

为了让它们可访问,我在static内部MyUtils(它没有自己的任何数据/函数成员)。在创建MyUtils之前,我的代码是线程安全

我担心,通过制作这些innerstatic,当它们的多个实例存在于整个文件中时,它们是否仍然是线程安全?或者他们的任何错误含义是否因为static而错过了?

编辑:我没有触及helper类中的任何共享变量。我唯一担心的是static类的实例是否是线程安全的(因为它们是static)。

5 个答案:

答案 0 :(得分:18)

如果你问这些是否有任何不良后果:

public class Helper1 {}

...为:

public class MyUtils {
    public static class Helper1 {}
}

然后不,没有。在这种情况下,static关键字只是将嵌套的内部类“提升”到顶级类,因此您可以实例化它而无需封闭的MyUtils实例。这是一篇关于这个主题的可通过的文章:

http://www.javaworld.com/javaworld/javaqa/1999-08/01-qa-static2.html

实质上,在嵌套的内部类上执行public static class X与在标准顶级类中执行public class X相同。

答案 1 :(得分:6)

“类”本身没有线程安全或线程安全的意义。因此,它是否是静态的是无关紧要的。

当某人引用一个线程安全或不是线程安全的类时,它们实际上意味着该类提供的功能是线程安全的。因此,这就是内部阶级自己做的事情,实际上会产生不同。

没有任何固有的方法可以使它们不可重入。当您开始访问共享变量等时会出现问题。因此,例如,方法访问的类的成员需要进行适当的同步。但是如果方法不存储任何状态等,那么就没有什么能阻止你跨多个线程使用它们。

希望有所帮助。

答案 2 :(得分:0)

您需要保护对help1的访问权限,因为这是一个实例级别(共享)变量。 如果您不允许它跳过该方法,help2是安全的。

静态类和从中创建的实例没有什么特别之处。 相同的线程安全规则也适用于静态类的实例,这些实例也适用于正常情况。

答案 3 :(得分:0)

静态方法和内部类没有对其动态计数器部分的变量的任何访问权限,因此不能在其父类的实例上使用监视器/同步。当然,这并不意味着声明它们并使用它们本质上是非线程安全的。只是如果您需要在父类的实例上同步任何这些静态方法,那么您需要确保在输入之前同步/锁定,否则您必须显式传递引用将父实例放入其中。

答案 4 :(得分:0)

我得到了答案。将MyUtils设为interface设计更简洁,因为我可以使用static类中的helper标识符