如何检查POJO的字段是否100%线程安全?

时间:2015-01-22 06:52:05

标签: java multithreading thread-safety pojo

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

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

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<?>是否有任何潜在的非线程安全字段,以便我不会缓存它们。

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

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

1 个答案:

答案 0 :(得分:2)

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

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

通常情况下,如果没有暂时打破不变的(即,从一个玩家的手中取出钱,然后将其添加到另一个玩家手中),方法就无法完成其工作。

如果一个线程可以创建一个不允许其他线程看到的临时条件,那么必须使用互斥(即synchronized块)来阻止其他线程看到它。执行临时损坏的方法必须在synchronized块内执行, AND 所有其他必须不允许查看临时损坏的方法也必须在{{1}每当他们数据时就会阻塞。

当您同步所有方法,以便没有任何方法可以看到由任何其他线程中调用的任何方法引起的临时错误状态时, THEN 您的整个程序将是线程安全的


PS:当一个线程没有可能的方法来查看处于错误状态的类的实例(即,破坏的不变量)而其他一些线程正在修改实例时,可以将类称为“线程安全”。