【问题标题】:How to check whether a POJO's fields are 100% thread safe?如何检查 POJO 的字段是否 100% 线程安全?
【发布时间】:2015-01-22 06:52:05
【问题描述】:

我想知道一个类是否有任何非线程安全的字段,这样我就不会将它们缓存在我的工厂中。

我编写了一个示例代码来测试一个类是否具有非线程安全的潜在字段。

final class ObjectStateChecker {

    public void isStateful(@NotNull Class<?> objectType) {
        for (Field field : Arrays.asList(objectType.getDeclaredFields())) {
            System.out.println("Field: " + field.getName());
            int modifiers = field.getModifiers();
            System.out.println("Modifier: " + modifiers);
            if (!Modifier.isFinal(modifiers)) {
                System.out.println("Field " + field + " is final.");
            } else {
                System.out.println("Field " + field + " is not final.");
            }
        }
    }

    private class Student {
        private String name;
        private final int age;

        private static final int SOME_VALUE = 1;

        private Student(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }
    }

    public static void main(String[] args) {
        ObjectStateChecker objectStateChecker = new ObjectStateChecker();
        Student student = objectStateChecker.new Student("Ram", 23);
        objectStateChecker.isStateful(student.getClass());
    }
}

如何增强 isStateful() 方法?目标是找出Class&lt;?&gt; 是否有任何潜在的非线程安全字段,以便我不会缓存它们。

更新: 除了检查公共同步方法之外,我还有什么需要考虑的吗?我认为所有 final 和 static 字段都是线程安全的,除非它们是不同步的集合。

我认为一定有一些图书馆做过类似的事情。对此类库的任何引用也很有用。我知道依赖注入容器。有没有这样的容器有我可以使用的有用的代码示例?

【问题讨论】:

  • 你可以另外检查,如果所有公共方法都同步了,那么所有字段都是安全的。
  • 上面的代码有什么问题/有什么问题?
  • @ErwinBolwidt 我不确定要检查的所有可能条件。
  • @Vitaly 谢谢。除了检查公共同步方法之外,我还有什么需要考虑的吗?我认为所有 final 和 static 字段都是线程安全的,除非它们不是未同步的集合
  • @BRS “线程安全”是什么意思?你应该从那开始。很难以有用的方式定义它。请注意,例如,同步类的所有公共字段并不意味着我不能编写涉及该类的多线程竞争条件。但是如果对“线程安全”的定义足够狭隘,您也许可以做出一些事情。

标签: java multithreading thread-safety pojo


【解决方案1】:

POJO 不能是线程安全的。 POJO 只是数据,线程安全不仅仅是数据的属性:线程安全是访问数据的方法的属性。请注意,当我说“方法”时,我指的是整个方法集。如果另一种方法不是线程安全的,那么一种方法就不能是线程安全的。

线程安全就是保护不变量。不变量是一个布尔测试,您可以针对必须始终为真的数据运行该测试。举个例子,如果你的程序是一个大富翁游戏,那么银行和所有玩家手中的现金总量必须始终加起来为相同的固定金额。

如果不临时打破不变量(即,从一个玩家手中取出钱,然后将其添加到另一个玩家手中),一个方法通常是不可能完成其工作的。 p>

如果一个线程可以创建一个不允许其他线程看到的临时条件,那么您必须使用互斥(即synchronized 块)来防止其他线程看到它.造成临时损坏的方法必须在 synchronized 块内进行,并且所有其他不允许看到临时损坏的方法也必须在 synchronized 块中,只要它们查看数据。

当您同步了所有方法以使任何方法都无法看到由任何其他线程中调用的任何方法引起的临时错误状态时,那么您的整个程序将是线程安全的.


P.S.:当一个线程无法在某个其他线程正在修改该实例时,一个线程无法看到处于不良状态(即损坏的不变量)的类的实例时,可以将一个类称为“线程安全”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-07
    • 2011-11-10
    • 2020-01-15
    • 2013-06-30
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多