相关疑难解决方法(0)

为什么`synchronized(new Object()){}`a no-op?

在以下代码中:

class A {
    private int number;

    public void a() {
        number = 5;
    }

    public void b() {
        while(number == 0) {
            // ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果调用方法b然后启动一个触发方法a的新线程,则方法b不能保证看到更改,number因此b可能永远不会终止.

当然,我们可以number volatile解决这个问题.但是出于学术原因,我们假设这volatile不是一个选择:

JSR-133的常见问题告诉我们:

在我们退出synchronized块之后,我们释放了监视器,它具有将缓存刷新到主内存的效果,因此该线程所做的写操作对其他线程是可见的.在我们进入同步块之前,我们获取监视器,它具有使本地处理器高速缓存无效的效果,以便从主存储器重新加载变量.

这听起来像我只需要两个ab进入和退出任何synchronized-Block,无论他们使用什么显示器.更确切地说,它听起来像这样......:

class A {
    private int number;

    public void a() {
        number = 5;
        synchronized(new Object()) {}
    }

    public void b() {
        while(number == 0) {
            // …
Run Code Online (Sandbox Code Playgroud)

java multithreading java-memory-model

53
推荐指数
2
解决办法
2723
查看次数

最终场的线程安全性

假设我有一个JavaBean 用户,它从另一个线程更新,如下所示:

public class A {

    private final User user;

    public A(User user) {
        this.user = user;
    }

    public void aMethod() {
        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                ...a long running task..
                user.setSomething(something);
            }

        });
        t.start();
        t.join();
    }

    public void anotherMethod() {
        GUIHandler.showOnGuiSomehow(user);
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码线程安全吗?我的意思是,当创建A实例并调用A.aMethod的线程读取用户字段时,它是否看到处于新鲜状态的用户?如何以适当的线程安全方式做到这一点?

请注意,我无法修改用户类,我不知道它本身是否是线程安全的.

java multithreading thread-safety

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