multithreading - Thread-safe class in Java by means of synchronized blocks -
let's have simple java class myclass
.
public class myclass { private int number; public myclass(int number) { this.number = number; } public int getnumber() { return number; } public void setnumber(int number) { this.number = number; } }
there 3 ways construct thread-safe java class has state:
make immutable
public class myclass { private final int number; public myclass(int number) { this.number = number; } public int getnumber() { return number; } }
make field
number
volatile
.public class myclass { private volatile int number; public myclass(int number) { this.number = number; } public int getnumber() { return number; } public void setnumber(int number) { this.number = number; } }
use
synchronized
block. classic version of approach described in chapter 4.3.5 of java concurrency in practice. , funny thing has error in example mentioned in errata book.public class myclass { private int number; public myclass(int number) { setnumber(number); } public synchronized int getnumber() { return number; } public synchronized void setnumber(int number) { this.number = number; } }
there 1 more fact should added context of discussion. in multhithreaded environment jvm free reorder instructions outside of synchronized
block preserving logical sequence , happens-before relationships specified jvm. may cause publishing object not constructed yet thread.
i've got couple of questions regarding third case.
will equivalent following piece of code:
public class myclass { private int number; public myclass(int number) { synchronized (this){ this.number = number; } } public synchronized int getnumber() { return number; } public synchronized void setnumber(int number) { this.number = number; } }
will reordering prevented in third case or possible jvm reorder intstructions , therefore publish object default value in field
number
?if answer second question yes have 1 more question.
public class myclass { private int number; public myclass(int number) { synchronized (new object()){ this.number = number; } } public synchronized int getnumber() { return number; } public synchronized void setnumber(int number) { this.number = number; } }
this strange-looking synchronized (new object())
supposed prevent reordering effect. work?
just clear, these examples don't have practical applications. i'm curious nuances of multithreading.
synchronized(new object())
nothing, since synchronization on object synchronize on. if thread synchronizes on oneobject
, , thread b synchronizes on anotherobject
, there no happens-before between them. since can know fact no other thread ever synchronize on new object()
create there, won't establish happens-before between other thread.
regarding synchronzied
in constructor, if object safely published thread, don't need it; , if it's not, you're in mess of trouble is. asked question on concurrency-interest list bit ago, , an interesting thread resulted. see in particular this email, points out constructor synchronized, in absence of safe publication thread see default values in fields, , this email (imho) ties whole thing together.
Comments
Post a Comment