当前位置: 首页 > 面试题库 >

具有非最终字段的不可变对象如何成为线程不安全的?

斜烈
2023-03-14
问题内容

说我们有这个

// This is trivially immutable.
public class Foo {
    private String bar;
    public Foo(String bar) {
        this.bar = bar;
    }
    public String getBar() {
        return bar;
    }
}

是什么使该线程不安全?接下来是这个问题。


问题答案:

Foo一旦安全发布,它就是线程安全的。例如,此程序可能会打印“不安全”(它可能不会使用hotspot /
x86的组合)-如果您进行bar最终定格,则不会发生:

public class UnsafePublication {

    static Foo foo;

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (foo == null) {}
                if (!"abc".equals(foo.getBar())) System.out.println("unsafe");
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                foo = new Foo("abc");
            }
        }).start();
    }
}


 类似资料:
  • 我得到的是它们是线程安全的。 杰里米·曼森博客的片段- 因为this引用存储在lastconstructed中“,因此转义构造函数 请建议。

  • 类OneValueCache是不可变的。但是我们可以更改变量缓存的引用。 但我不能理解为什么VolateCachedFactorizer类是线程安全的。 对于两个线程(线程A和线程B),如果线程A和线程B同时到达,那么两个线程A和B都将尝试创建OnEvalueCache。然后线程A到达而线程B同时到达。然后线程A将创建一个,它覆盖threadB创建的值(OneValueChange是不可变的,但是

  • 问题内容: 为了线程安全,是否应该是故意不可变的Java类’final’的所有字段(包括超字段),还是没有修饰符方法就足够了? 假设我有一个带有非最终字段的POJO,其中所有字段都是某种不可变类的类型。这个POJO有getters- setters和一个设置一些初始值的构造函数。如果我通过敲除修饰符方法来扩展此POJO,从而使其不可变,那么扩展类是否是线程安全的? 问题答案: 为了以线程安全的方式

  • 问题内容: 我正在阅读Joshua Bloch撰写的Effective Java 项目15 。在第15项中,谈到“最小化可变性”时,他提到了使对象不可变的五个规则。其中之一是使所有字段最终确定。这是规则: 将所有字段都设为最终字段 :这可以通过系统强制地表达您的意图。同样,如果对新创建实例的引用从一个线程传递到另一个线程而没有同步,则必须确保正确的行为,如在内存模型中阐明的那样[JLS,17.5;

  • 问题内容: 我是Go的新手,我需要创建一个线程安全的变量。我知道在Java中您只能使用关键字,但是似乎没有类似的东西存在。有什么方法可以同步变量? 问题答案: Java中的一种意思是仅允许单个线程(在任何给定时间)执行代码块。 在Go中,有很多构造可以实现该目标(例如互斥体,通道,等待组,中的原语),但是Go的谚语是: “不要通过共享内存进行通信;而是通过通信来共享内存。” 因此,不要锁定和共享变

  • 定义不可变类的策略表明 所有字段都应该是最终字段。 对于ex: 为什么一定要最终决定? 因为我没有给出setter方法吗?它不能改变。谢谢。