在Java中初始化对象Thread Safe

Suy*_*ash 0 java multithreading initialization object

我在我的一个应用程序中编写了类似的代码,但我不确定它是否是线程安全的.

public class MyClass {
    private MyObject myObject = new MyObject();

    public void setObject(MyObject o) {
        myObject = o;
    }

    public MyObject getObject() {
        return myObject;
    }
}
Run Code Online (Sandbox Code Playgroud)

setObject()getObject()方法将通过不同的线程调用.该getObject()方法将由持续绘制Canvas的线程调用.为了获得最佳FPS和平滑运动,我不希望该线程一直等待同步锁定.因此,除非确实有必要,否则我希望避免使用同步.那么这里真的有必要吗?或者还有其他更好的方法来解决这个问题吗?

顺便说一句,线程是否收到对象的旧副本并不重要.

Mar*_*nik 5

至于当前版本的状态,它绝对不是线程安全的,因为并发访问myObject将建立数据竞争.

你没有指定它,但如果MyObject它不是线程安全的,那么你的程序将不是线程安全的,无论你对你所显示的代码做什么.

线程是否收到对象的旧副本并不重要.

Java内存模型允许比通过数据竞争访问的对象更糟糕的事情:

  • 一个线程可能总是收到同一个对象(它碰巧读到的第一个对象);
  • 一个线程可以观察该对象只有一些可达到的值被初始化(一个被撕裂的对象).

为了获得最佳FPS和平滑运动,我不希望该线程一直等待同步锁定.

您是否花了很多精力来衡量线程等待锁定的时间?我的猜测:你没有,因为时间太短,无法察觉.

但是,您的情况甚至不会调用锁:只需使您的实例变量volatile足以保证线程之间安全共享对象.