相关疑难解决方法(0)

Java Object Reference的发布不正确

下面的例子来自Brian Goetz的书"Java Concurrency in Practice",第3章,第3.5.1节.这是不正确发布对象的示例

class someClass {
    public Holder holder;

    public void initialize() {
        holder = new Holder(42);
    }
}

public class Holder {
  private int n;
  public Holder(int n) { this.n = n; }

  public void assertSanity() {
    if (n!=n)
      throw new AssertionError("This statement is false");
  }
}
Run Code Online (Sandbox Code Playgroud)

它表示Holder可能出现在另一个处于不一致状态的线程中,而另一个线程可能会观察到部分构造的对象.怎么会发生这种情况?你能用上面的例子给出一个场景吗?

此外,它继续说有一种情况,当一个线程第一次读取一个字段时可能会看到一个陈旧的值,然后下次再看到一个更新的值,这就是assertSanity可以抛出断言错误的原因.如何抛出assertionError?

从进一步阅读,解决这个问题的一种方法是通过使变量'n'最终使Holder不可变.现在,让我们假设持有人不是无法忍受的,而是有效的不可改变的.为了安全地发布这个对象,我们是否必须使holder初始化为静态并将其声明为volatile(静态初始化和volatile或者只是volatile)?就像是

public class someClass {
    public static volatile Holder holder = new Holder(42);

}
Run Code Online (Sandbox Code Playgroud)

感谢您的帮助.

java concurrency

21
推荐指数
1
解决办法
1471
查看次数

volatile,final和synchronized之间安全发布的差异

给定具有变量x的A类.变量x在类构造函数中设置:

A() {
x = 77;
}
Run Code Online (Sandbox Code Playgroud)

我们想将x发布到其他一些线程.考虑以下3个变量x线程安全(?)发布的情况:

1)x是最终的

2)x是易变的

3)x在同步块中设置

synchronized(someLock) {
A a  = new A();
a.x = 77;
}
Run Code Online (Sandbox Code Playgroud)

Thread2只打印x:

 System.out.println(a.x);
Run Code Online (Sandbox Code Playgroud)

问题是:是否可以观察到Thread2打印的'0'?或者JMM保证将打印'77'或者在所有3种情况下都会抛出NPE?

java concurrency

5
推荐指数
1
解决办法
1085
查看次数

初始化对象的Java线程安全性

考虑以下课程:

public class MyClass
{
    private MyObject obj;

    public MyClass()
    {
        obj = new MyObject();
    }

    public void methodCalledByOtherThreads()
    {
        obj.doStuff();
    }
}
Run Code Online (Sandbox Code Playgroud)

由于obj是在一个线程上创建并从另一个线程访问的,因此当调用methodCalledByOtherThread时,obj可能为null吗?如果是这样,将obj声明为volatile是解决此问题的最佳方法吗?声明obj作为最终会有什么不同吗?

编辑:为清楚起见,我认为我的主要问题是:其他线程是否可以看到obj已经被某个主线程初始化或者obj可能是陈旧的(null)?

java concurrency thread-safety

2
推荐指数
1
解决办法
1100
查看次数

为什么类结构语言中的构造函数通常被视为线程安全?

(我希望我可以为实现线程的所有类构造语言标记这个问题,但是这里有Java,C++,C#和Ruby.不是我对所有这些都很酷)

我想我已经在博客文章/教程上看到过这种效果的陈述(类构造函数是线程安全的).我无法追踪任何直接的陈述,但许多帖子和教程都做出了假设,或者甚至没有提到在构造函数和析构函数上运行的线程问题.坚持Java,它有一个历史和一些正式的多线程方法,

Javamex

扬科夫的教程

Oracle教程

所有这些文章/网页都以自信的方式编写,并包含全面的讨论.他们都提到了方法同步的Java特性,所以你希望他们可能会提到这会如何影响构造和破坏的特殊方法.但他们没有.

但类构造函数和析构函数需要像任何类方法一样考虑.这是一篇关于Java的文章,

Java中的安全构造技术

关于从构造函数泄漏'this'引用.这里有几个StackOverflow帖子,

Java中不完整构造的对象,

Java构造函数需要锁定

显示具有线程问题的构造函数.我怀疑特殊方法中的线程问题仅限于Java.

所以,我想知道,

  • 是否基于构造函数的总体布局假设了线程安全(无论如何定义)?一个代码不多的紧密编码的构造函数将接近可重入代码(通过参数接受数据等)

  • 或者口译员/编制者是否处理具有特殊待遇或保护的施工人员/破坏者?例如,Java内存模型在构造结束时对期望做出一些评论,我希望其他语言规范也是如此.

维基百科关于构造函数的内容很少.在不同的上下文中,这篇文章中的构造语言中的构造函数包含一些提示,但不是关于线程安全性.

虽然在专业书籍中有许多信息,但是对StackOverflow进行一般性(尽管语言特定的提及很有趣!)解释/讨论会很好.

c# c++ ruby java

2
推荐指数
1
解决办法
134
查看次数

标签 统计

java ×4

concurrency ×3

c# ×1

c++ ×1

ruby ×1

thread-safety ×1