如何让java类线程安全?

2023-11-23

我有一个java类如下

 class User {

    String name;
    String phone;

    public String getName() {
        return name;
    }

    public String getPhone() {
        return phone;
    }

}

该类的使用方式是,为每个线程创建 1 个该 User 类的对象。现在,由于每个线程都有一个对象副本,我可以将此类称为线程安全的吗?

我需要同步这些方法吗?


对于一个线程安全的类,无论有多少线程访问它,它的不变量和后置条件都应该成立。

对于此类,虽然没有写入方法,但仍然需要同步读取。这是因为编译器可以缓存状态变量(在本例中name and phone)对于每个线程(记住每个线程都有自己的一组寄存器)。因此,如果一个线程更新任何状态变量的值,另一个线程可能看不到它,并且可能会读取过时的值。

避免这种情况的一个非常简单的方法是使状态变量volatile。但它是一个弱同步原语,并且不提供像synchronized does.

这是使此类线程安全的正确方法:

 class User {

    GuardedBy("this")String name;
    GuardedBy("this")String phone;

    public synchronized String getName() {
        return name;
    }

    public synchronized String getPhone() {
        return phone;
    }

}

注意:每个状态变量可以使用不同的锁,具体取决于您的要求。我假设这两个变量以某种方式一起参与一个不变量。

弱同步:

 class User {

    volatile String name;
    volatile String phone;

    public String getName() {
        return name;
    }

    public String getPhone() {
        return phone;
    }

}

For synchronized方法,每次线程调用它们时,它都会刷新其缓存并从内存中读取最新值,并且每次存在时synchronized方法,它将变量的最新值放入内存中。

过时的读取可能会更加危险64b double and long,因为在 Java 中写入和读取这些数据类型不是原子的,可以在 2 中完成32b运营。这可能会导致一些非常糟糕的后果。

编辑:刚刚看到每个线程都有自己的对象副本。在这种情况下,不需要同步。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何让java类线程安全? 的相关文章

随机推荐