I understand that to achieve thread safety and synchronization we use either synchronized block or method.
But I am not able to understand the statement-
"A synchronized block in Java is synchronized on some object"
Any real world example will be helpful.
The effect of synchronized is that only one thread at a time can execute the synchronized code. But if we look at the details, that's not the whole truth.
Suppose we have two Vectors A and B and want to call various methods from different threads. The Vector class is thread-safe by synchronizing all important methods. When thread T1 executes A.add(5,"abc"), why should that block a different thread from executing B.get(5)? They have no data elements in common, so executing both calls in parallel won't hurt.
And here comes the notion of "synchronized on A": The Vector methods synchronize on the Vector instance, so at most one thread can execute synchronized code for any given Vector.
So Vector A synchronizes on A, and Vector B on B. So, no two threads can manipulate the Vector A in parallel, but one thread can work on A, and another one independently on B.
With the synchronized(object) { ... } construct, you decide on the object you want to synchronize on.
Using the synchronized keyword on an instance method, you get synchronization on the current (this) object, so every instance gets its own synchronization.
Using the synchronized keyword on a static method, you get synchronization on the class, so you get protection against all other static synchronized methods of this class, independent of any instance.
3 usages of synchronized keyword.
Explictly:
final Object object = new Object();
synchronized(object) {
}
Instance synchronized method
synchronized void foo() {
}
it will use current instance as monitor lock, which equals:
void foo() {
synchronized (this) {
}
}
So when you call foo on different instances, they will not effect each other.
Class synchronized method
class Exmaple {
static synchronized void foo() {
}
}
it will use current class object as monitor lock, which equals:
class Exmaple {
static void foo() {
synchronized (Exmaple.class) {
}
}
}
Synchronization takes a lock (Object level lock or Class level lock) on an object before executing the synchronized block.
A synchronized block in Java thus is synchronized on the object on which it takes the lock.
For example:
synchronized (this) // Lock on current object
synchronized (lockObject) // Lock on an object lockObject
synchronized(ClassA.class) // Lock on ClassA
Let say that I have a singleton:
public class MySinglton {
private static volatile MySinglton s;
private int x;
public static MySinglton getInstance() {
if (s != null) return s;
synchronized (MySinglton.class) {
if (s == null) {
s = new MySinglton();
}
}
return s;
}
public void setX(int x){
this.x = x;
}
}
Ok, method getInstance is thread safe. My question is. Is it necessary to modify method setX, or it is thread safe because getInsatnce method is thread safe. If it is not what is better.
synchronized public void setX(int x){
this.x = x;
}
public void setX(int x){
synchronized (this) {
this.x = x;
}
}
or finally
ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public void setX(int x){
readWriteLock.readLock().lock();
this.x = x;
readWriteLock.readLock().unlock();
}
Just because getInstance() is thread safe, that does not mean any other methods of the class are thread safe. Multiple threads can still perform operations on the singleton object simultaneously.
You should synchronize a private final class member object inside the setX function. Do not synchronize this and do not synchronize the entire method. Synchronizing this synchronizes the object and if other code also synchronized the object returned by getInstance(), you could have yourself a deadlock. Putting the synchronized keyword before methods means that only one synchronized method of the synchronized methods in your class can be executed by a thread on an instance at any given time. It can also give the impression to clients/consumers of the class that the class is thread safe even though it may not be.
A good approach to writing a singleton is to use an enum as that guarantees there will only ever be one instance of it. However, the member functions of the enum will still need to be synchronized if you want it to be thread safe. See page 311 of Effective Java for an example of this: http://uet.vnu.edu.vn/~chauttm/e-books/java/Effective.Java.2nd.Edition.May.2008.3000th.Release.pdf
No setX is not thread safe as there might be multiple threads having reference of singleton's instance and they may try to execute setX api on the same instance.
You will need to make setX threadsafe. Both your method implementation with synchronized keyword would work.
I would not use read lock of readWriteLock as am writing a value to it. Also what if say something happens in between you acquire lock and unlock? You would ever unlock and hence lead to deadlock. So always use lock and unlock in try/catch/finally block where you unlock in finally block.
Having a singleton doesn't prevent multiple threads from calling setX() at the same time. So you definitely need synchronized here.
And it seems awkward to fetch a READ lock before WRITING. Point is: readers (that invoke a missing method "getX()") need a readlock; when writing, you want a WRITE lock!
To be precise: you need a ReadWrite lock if the property that is updated isn't "atomic" AND your program "knows" different "reader" and "writer" roles.
If there is just a "setX()" method (and no readers around, then "synchronized" should do; in that case you don't need a RW lock).
setX is called on an instance of s. So there is only one instance of s at any given time in the JVM (bcos it's a singleton). If two threads simulataeneously call setX, they could both ovewrite the same x or step on each other.
For eg.
Without Synchronization, if a thread A & thread B update x at the exact same point in time, other threads accessing these values may see different values for x.
setX is not implicitly threadsafe.
This is a good to have
public void setX(int x){
synchronized (this) {
this.x = x;
}
}
Here is a similar post Java fine-grained synchronization in getter/setter methods and singleton pattern of a class
public final class MySinglton
{
private final static MySinglton s;
private volatile int x;
static {
s = new MySinglton();
}
private MySinglton() {}
public static MySinglton getInstance()
{
return s;
}
public void setX(int x)
{
this.x = x;
}
}
If you do not have any other requirements for you Singleton you can go with this. Provide a default constructor to avoid other instances and mark the class as final so noone can extend it.
Placing the initialization in a static block will work fine for most programs. If you encounter problems just wrap it in a static inner class.
All you have shown us is a singleton object with a method setX(int x). But, the setX(x) method doesn't do anything except set a private variable that no other class can see.
You haven't shown us any code that uses x. Until you show us how x is used, "thread safe" means nothing.
"Thread safety" is all about making sure that your program will do what you want it to do no matter how the executions of its threads are interleaved. What do you want your program to do?
Sometimes we talk about a "thread safe" class. People say, for example, that java.util.concurrent.ArrayBlockingQueue is "thread-safe". But that only means that the threads in your program can not put an ArrayBlockingQueue into a bad internal state. It does not mean that the queue will always contain the objects that your program wants it to contain or, in the order that your program wants. Building a program out of "thread safe" objects does not make the program thread safe.
What other methods are in your MySingleton class? How is it supposed to be used?
This question already has answers here:
object synchronization
(2 answers)
Closed 9 years ago.
If I have a synchronised method in a class then the synchronization is applied only on the class or also on the objects which the method is modifing.
For example if I have a class A as below
public class A {
private int x;
public void setX(int x) {
this.x = x;
}
}
And there are two classes B and C which are having some method to set the value of x. Like
public class B implements Runnable {
private A a;
public B(A a) {
this.a = a;
}
public synchronized void setX(A a) {
int tempX = 0;
.... //Some logic to calculate tempX value
a.setX(tempX);
}
#Override
public void run() {
this.setX(a);
}
}
Class C will also have a synchronised method to set value of x.
Now if I create an object of A and pass the same object to B and C, will the synchronization happen on object a also or we need to synchronize setX of class A.
Note: Since I am learning threads, so please bear with me if the question sound stupid. I am just trying to understand what all happens if a synchronized method is called.
The code that you've shown synchronises on an instance of B. Presumably, your other method will synchronise on an instance of C. Therefore, you're looking at two separate locks - the methods won't lock each other out at all, and you haven't really synchronised anything.
As you are passing in a A class to your setX method, it will be this which is set, not your private A class.
Also, there is no relationship whatever between B.setX and C.setX so there will be two completely different synchronizations.
In reality, setting synchronization on A.setX would be more meaningful.
Each synchronized method or block specifies or implies some object. For a static method it is the class object for its class. For a non-static method it is the target object, its this.
Synchronization operates among methods and blocks that synchronize on the same object. Synchronization has no impact on non-synchronized code, or on code that is synchronized on a different object.
Your synchronized method would only synchronize with code that is synchronized on the same B instance.
Java Code:
public class IncreaseTest {
public static int value = 0;
public synchronized int increment() {
return value++;
}
}
Is method increment() thread-safe? Do I have to add the modifier keyword volatile as follows:
public static volatile int value = 0;
This code is not thread-safe. The instance method will synchronize on an instance, if you have multiple instances they will not use the same monitor and therefor the updates can interleave.
You either need to remove the static from the value field or add static to the increment() method.
Also, as you have made value public, there is the additional problem that value can be changed or read outside of this method without using synchronisation which could result in reading old values.
So changing your code to the following will make it thread-safe:
public class IncreaseTest {
private int value = 0;
public synchronized int increment() {
return value++;
}
}
You should probably use atomicvars
If you are using this method in two threads then you do need the volatile keyword. Without it, another thread may not get the most up to date value. (C#)
I do not think this is thread safe since the static variable is public and can be accessed by other threads in a non-thread safe manner. In order to be thread safe you must declare the variable as follows:
public static volatile int value;
Now value being volatile, will be accessed in a synchronized block.
I am reading the book Java Concurrency in Practice session 4.3.5
#ThreadSafe
public class SafePoint{
#GuardedBy("this") private int x,y;
private SafePoint (int [] a) { this (a[0], a[1]); }
public SafePoint(SafePoint p) { this (p.get()); }
public SafePoint(int x, int y){
this.x = x;
this.y = y;
}
public synchronized int[] get(){
return new int[] {x,y};
}
public synchronized void set(int x, int y){
this.x = x;
this.y = y;
}
}
I am not clear where It says
The private constructor exists to avoid the race condition that would occur if the copy constructor were implemented as this (p.x, p.y); this is an example of the private constructor capture idiom (Bloch and Gafter, 2005).
I understand that it provides a getter to retrieve both x and y at once in a array instead of a separate getter for each, so the caller will see consistent value, but why private constructor ? what's the trick here
There are already a bunch of answers here, but I would really like to dive into some details (as much as my knowledge let's me). I will strongly advise you to run each sample that is present here in the answer to see for yourself how things are happening and why.
To understand the solution, you need to understand the problem first.
Suppose that the SafePoint class actually looks like this:
class SafePoint {
private int x;
private int y;
public SafePoint(int x, int y){
this.x = x;
this.y = y;
}
public SafePoint(SafePoint safePoint){
this(safePoint.x, safePoint.y);
}
public synchronized int[] getXY(){
return new int[]{x,y};
}
public synchronized void setXY(int x, int y){
this.x = x;
//Simulate some resource intensive work that starts EXACTLY at this point, causing a small delay
try {
Thread.sleep(10 * 100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.y = y;
}
public String toString(){
return Objects.toStringHelper(this.getClass()).add("X", x).add("Y", y).toString();
}
}
What variables create the state of this object? Just two of them : x,y. Are they protected by some synchronization mechanism? Well they are by the intrinsic lock, through the synchronized keyword - at least in the setters and getters. Are they 'touched' anywhere else? Of course here:
public SafePoint(SafePoint safePoint){
this(safePoint.x, safePoint.y);
}
What you are doing here is reading from your object. For a class to be Thread safe, you have to coordinate read/write access to it, or synchronize on the same lock. But there is no such thing happening here. The setXY method is indeed synchronized, but the clone constructor is not, thus calling these two can be done in a non thread-safe way. Can we brake this class?
Let's try this out:
public class SafePointMain {
public static void main(String[] args) throws Exception {
final SafePoint originalSafePoint = new SafePoint(1,1);
//One Thread is trying to change this SafePoint
new Thread(new Runnable() {
#Override
public void run() {
originalSafePoint.setXY(2, 2);
System.out.println("Original : " + originalSafePoint.toString());
}
}).start();
//The other Thread is trying to create a copy. The copy, depending on the JVM, MUST be either (1,1) or (2,2)
//depending on which Thread starts first, but it can not be (1,2) or (2,1) for example.
new Thread(new Runnable() {
#Override
public void run() {
SafePoint copySafePoint = new SafePoint(originalSafePoint);
System.out.println("Copy : " + copySafePoint.toString());
}
}).start();
}
}
The output is easily this one:
Copy : SafePoint{X=2, Y=1}
Original : SafePoint{X=2, Y=2}
This is logic, because one Thread updates=writes to our object and the other is reading from it. They do not synchronize on some common lock, thus the output.
Solution?
synchronized constructor so that the read will synchronize on the same lock, but Constructors in Java can not use the synchronized keyword - which is logic of course.
may be use a different lock, like Reentrant lock (if the synchronized keyword can not be used). But it will also not work, because the first statement inside a constructor must be a call to this/super. If we implement a different lock then the first line would have to be something like this:
lock.lock() //where lock is ReentrantLock, the compiler is not going to allow this for the reason stated above.
what if we make the constructor a method? Of course this will work!
See this code for example
/*
* this is a refactored method, instead of a constructor
*/
public SafePoint cloneSafePoint(SafePoint originalSafePoint){
int [] xy = originalSafePoint.getXY();
return new SafePoint(xy[0], xy[1]);
}
And the call would look like this:
public void run() {
SafePoint copySafePoint = originalSafePoint.cloneSafePoint(originalSafePoint);
//SafePoint copySafePoint = new SafePoint(originalSafePoint);
System.out.println("Copy : " + copySafePoint.toString());
}
This time the code runs as expected, because the read and the write are synchronized on the same lock, but we have dropped the constructor. What if this were not allowed?
We need to find a way to read and write to SafePoint synchronized on the same lock.
Ideally we would want something like this:
public SafePoint(SafePoint safePoint){
int [] xy = safePoint.getXY();
this(xy[0], xy[1]);
}
But the compiler does not allow this.
We can read safely by invoking the *getXY method, so we need a way to use that, but we do not have a constructor that takes such an argument thus - create one.
private SafePoint(int [] xy){
this(xy[0], xy[1]);
}
And then, the actual invokation:
public SafePoint (SafePoint safePoint){
this(safePoint.getXY());
}
Notice that the constructor is private, this is because we do not want to expose yet another public constructor and think again about the invariants of the class, thus we make it private - and only we can invoke it.
The private constructor is an alternative to:
public SafePoint(SafePoint p) {
int[] a = p.get();
this.x = a[0];
this.y = a[1];
}
but allows constructor chaining to avoid duplication of the initialization.
If SafePoint(int[]) were public then the SafePoint class couldn't guarantee thread-safety because the contents of the array could be modified, by another thread holding a reference to the same array, between the values of x and y being read by the SafePoint class.
Constructors in Java can not be synchronized.
We can not implement public SafePoint(SafePoint p) as { this (p.x, p.y); } because
As we are not synchronized(and can't as we are in the constructor),
during the execution of the constructor, someone may be calling SafePoint.set() from the different thread
public synchronized void set(int x, int y){
this.x = x; //this value was changed
--> this.y = y; //this value is not changed yet
}
so we will read the object in the inconsistent state.
So instead we create a snapshot in a thread-safe way, and pass it to the private constructor. The stack confinement protects the reference to the array, so there's nothing to worry about.
update
Ha! As for the trick everything is simple - you have missed #ThreadSafe annotation from the book in your example:
#ThreadSafe
public class SafePoint { }
so, if the constructor which takes int array as an argument will be public or protected, the class will no longer be thread-safe, because the content of the array may change the same way as the SafePoint class(i.e. someone may change it during the constructor execution)!
I understand that it provides a getter to retrieve both x and y at once in a array instead of a separate getter for each, so the caller will see consistent value, but why private constructor ? what's the trick here?
What we want here is chaining of constructor calls to avoid code duplication. Ideally something like this is what we want:
public SafePoint(SafePoint p) {
int[] values = p.get();
this(values[0], values[1]);
}
But that won't work because we will get a compiler error:
call to this must be first statement in constructor
And we can't use this either:
public SafePoint(SafePoint p) {
this(p.get()[0], p.get()[1]); // alternatively this(p.x, p.y);
}
Because then we have a condition where the values might have been changed between the call to p.get().
So we want to capture the values from SafePoint and chain to another constructor. That is why we will use the private constructor capture idiom and capture the values in a private constructor and chain to a "real" constructor:
private SafePoint(int[] a) {
this(a[0], a[1]);
}
Also note that
private SafePoint (int [] a) { this (a[0], a[1]); }
does not make any sense outside the class. A 2-D point has two values, not arbitrary values like the array suggests. It has no checks for the length of the array nor that it is not null. It is only used within the class and the caller knows it is safe to call with two values from the array.
Purpose of using SafePoint is to always provide a consistent view of x & y.
For example, consider a SafePoint is (1,1). And one thread is trying to read this SafePoint while another thread is trying to modify it to (2,2). Had safe point not been thread safe it would have been possible to see views where the SafePoint would be (1,2) (or (2,1)) which is inconsistent.
First step towards providing a thread safe consistent view is not to provide independent access to x & y; but to provide a method to access them both at same time. Similar contract applies for modifier methods.
At this point if a copy constructor is not implemented inside SafePoint then it is completely. But if we do implement one we need to be careful. Constructors cannot be synchronized. Implementations such as following will expose a inconsistent state because p.x & p.y are being accessed independently.
public SafePoint(SafePoint p){
this.x = p.x;
this.y = p.y;
}
But following will not break thread safety.
public SafePoint(SafePoint p){
int[] arr = p.get();
this.x = arr[0];
this.y = arr[1];
}
In order to reuse code a private constructor that accepts an int array is implemented that delegates to this(x, y). The int array constructor can be made public but then in effect it will be similar to this(x, y).
The constructor is not supposed to be used outside this class. The clients shouldn't be able to build an array and pass it to this constructor.
All the other public constructors imply that the get method of SafePoint will be called.
The private constructor would allow you to build your own in a , probably, Thread unsafe way (i.e. by retrieving the x,y separately, building an array and passing it)
The private SafePoint(int[] a) provides two functionalities:
First, prevent others from using following constructor, becasue other threads can obtain the ref to the array, and may change the array while constructing
int[] arr = new int[] {1, 2};
// arr maybe obtained by other threads, wrong constructor
SafePoint safepoint = new SafePoint(arr);
Second, prevent later programmers from wrongly implementing the copy constructor like following. That's why author said:
The private constructor exists to avoid the race condition that would occur if the copy constructor were implemented as this(p.x, p.y)
//p may be obtined by other threads, wrong constructor
public SafePoint(SafePoint p) { this(p.x, p.y);}
See author's implementation: you don't have to worry p is modified by other threads,as the p.get() return a new copy, also p.get() is guarded by p's this, so p will not changed, even obtained by other threads!
public SafePoint(SafePoint p) {
this(p.get());
}
public synchronized int[] get() {
return new int[] {x, y};
}
What does it mean is, if you did not have a private constructor and you implement copy constructor in following way:
public SafePoint(SafePoint p) {
this(p.x, p.y);
}
Now assume that thread A is having the access to SafePoint p is executing above copy constructor's this(p.x, p.y) instruction and at the unlucky timing another thread B also having access to SafePoint p executes setter set(int x, int y) on SafePoint p. Since your copy constructor is accessing p's x and y instance variable directly without proper locking it could see inconsistent state of SafePoint p.
Where as the private constructor is accessing p's variables x and y through getter which is synchronized so you are guaranteed to see consistent state of SafePoint p.
Our requirement is: we want to have a copy constructor like below (at the same time ensuring class is still thread safe):
public SafePoint(SafePoint p){
// clones 'p' passed a parameter and return a new SafePoint object.
}
Let's try to make the copy constructor then.
Approach 1:
public SafePoint(SafePoint p){
this(p.x, p.y);
}
The problem with above approach is that it will render our class NOT THREAD SAFE
How ?
Because constructor is NOT synchronised, meaning it is possible that two threads can simultaneously act on the same object (one thread might clone this object using it's copy constructor and other thread might invoke object's setter method). And if this happens, the threads that invoked the setter method could have updated the x field (and yet to update the y field) thereby rendering the object in an inconsistent state. Now at this point, if the other thread (which was cloning the object), executes (and it can execute because constructor is not synchronised by intrinsic lock) the copy constructor this(p.x, p.y), p.x would be the new value, while p.y would still be old.
So, our approach is not thread safe, because constructor is not synchronised.
Approach 2: (Trying to make approach 1 thread safe)
public SafePoint(SafePoint p){
int[] temp = p.get();
this(temp[0], temp[1]);
}
This is thread safe, because p.get() is synchronised by intrinsic lock. Thus while p.get() executes, other thread could not execute the setter because both getter and setter are guarded by the same intrinsic lock.
But unfortunately the compiler won't allow us do this because this(p.x, p.y) should be the first statement.
This brings us to our final approach.
Approach 3: (solving compilation issue of approach 2)
public SafePoint(SafePoint p){
this(p.get());
}
private SafePoint(int[] a){
this(a[0], a[1]);
}
With this approach, we are guaranteed that our class is thread safe and we have our copy constructor.
One final question remaining is why is the second constructor private ?
This is simply because we create this constructor just for our internal purpose and we don't want client to create SafePoint object by invoking this method.