safe publication of mutable object

雨燕双飞 提交于 2019-12-05 07:24:23

Actually I think that volatile is the simplest to explain here. Unsafe publication happens when operations can be reordered and volatile prevents that. I could explain more probably, but it's already explained far more accurate than I will do.

Basically underneath there will be proper memory barriers inserted that will prevent re-orderings, as explained here. Essentially, what volatile does, is that if a ThreadA reads a volatile update performed by ThreadB, it is guaranteed to also see all the updates that were done before that volatile write.

final makes things safe too and it's specifically written in the JLS.

But there are two cases here according to : Storing a reference to it into a final field of a properly constructed object.

So according to the JLS, this is safe publication:

class Holder {
    private final int n; // making final here
}

There are proper memory barriers inserted btw that prevent stores in the constructor to be re-ordered with publishing the reference itself.

What about this example?

static class Holder {

   private int n;

   public void setN(int n){
      this.n = n;
   }
}

And somewhere else:

 class Other {
    final Holder holder;
    Other(){
        holder = new Holder();
        holder.setN(12);
    }
 }

It looks like this is still safe publication according to this

Make the integer volatile & synchronize it to a locking object with the thread in which you are concurring with.

This isn't the exact code but more of an idea for you to wrap your head around. No two things can operate on one thing at once. Thats what causes deadlocks in programs and even operating systems.

Class1:

public static final Object lock = new Object();
private Holder holder;
public abstract void method1(); //Assume these two go to different places
public abstract void method2(); //At different times w/ different implementations

Thread1:

public void method1() {
    synchronized(Class1.lock) {
        holder.assertMadness();
    }
}

Thread2:

public void method2() {
    synchronized(Class1.lock) {
        holder.assertMadness();
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!