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.
Related
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?
I am working through a Java book and found the following question.
In the code below, is the class threadsafe?
public class Queen
{
public int x;
public synchronized int getX()
{
return x;
}
public synchronized void setX(int x)
{
this.x = x;
}
public static void main(String args[])
{
}
}
My answer would be yes, since there are only two methods, both synchronized, so while one of them is running, it holds the lock on the object, and the other cannot run.
However, the official answer is NO, and the explanation is that the variable int x is public and can be modified by a thread while the other thread is inside one of the synchronized methods. Is that possible?? Doesn't the synchronized method hold the thread on this, meaning everything in that object including public variables?
All that the synchronized keyword does is automatically prevent multiple calls to synchronized methods on a single instance of an object. That means that whenever a synchronized method is called, it must be exited before any other synchronized methods can execute on the same instance.
However, direct field access is never affected by any form of locking in Java, so the public field makes this class quite unsafe.
You are right lock is kept on object , however it means that only one thread can be inside any of syncronised method. But the field is public so other threads need not to inside sycronized block.
Let say at time T1 , one thread in inside the setX() by calling
queenInstance.setX(10);
Howwver, at same instance other thread is trying to set value for this variable :-
queenInstance.x = 12;
It is unpredicatable what will be output.
The sole purpose of making the setter and getter synchronized is to prevent a race condition while accessing it. But since x is public any code can directly access it without using setter OR access it without using getter. Making x public will negate all the security provided by Synchronized methods.
If I use a Collection which is not thread safe and I just do some get on (Add in a static bloc), and the elements which are put in, have thread safe methods, that's thread safe ?
Moreover, "static final" variables are they thread safe ?
In last, the example above are they equals ?
Example 1 :
public class Test {
private static int cpt = 1;
public synchronized void increment(){
i++;
}
}
Example 2 :
public class Test {
private static Data cpt = new Data(1);
public void increment(){
cpt.inc();
}
}
public class Data {
private int compt;
public Data(int cpt){
compt = cpt;
}
public synchronized void inc(){
compt++;
}
}
Example 3 :
public class Test {
private static Data cpt = new Data(1);
public void increment(){
synchronized(cpt){
cpt.inc();
}
}
}
public class Data {
private int compt;
public Data(int cpt){
compt = cpt;
}
public void inc(){
compt++;
}
}
Thanks you very much ! :)
A static final object MAY be thread-safe IF it is IMMUTABLE. If it mutable and does not provide internal thread-safety, it is not thread safe.
As SJuan76 pointed out, example 1 is not thread-safe because you synchronized on the instance this by making the method an instance method. If the method were static it would be thread-safe. It is also considered poor design practice to synchronize on an instance that other code has access to and could also obtain a lock upon. By doing the default synchronize on an instance method, you lock on that instance. Since the caller has a reference to that instance, the caller could also get a synchronized lock on that instance. The same is true (even more so) by making the method static. Then the lock is acquired on the class object, any other code could then acquire a lock on the class, even without a specific instance.
Examples 2 & 3 are equivalently thread-safe as both synchronize on the Data instance that is held privately.
Static Final Variables are they thread safe?
final fields also allow programmers to implement thread-safe immutable objects without synchronization. A thread-safe immutable object is seen as immutable by all threads, even if a data race is used to pass references to the immutable object between threads. This can provide safety guarantees against misuse of an immutable class by incorrect or malicious code. final fields must be used correctly to provide a guarantee of immutability.
Memory that can be shared between threads is called shared memory or heap memory.
All instance fields, static fields, and array elements are stored in heap memory. In this chapter, we use the term variable to refer to both fields and array elements.
Local variables (§14.4), formal method parameters (§8.4.1), and exception handler parameters (§14.20) are never shared between threads and are unaffected by the memory model.
Above information came from here (http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html)
static fields could be thread safe and final fields could be depending on how it is used , so final static could be if used properly.
So final static or final is sort of the same thing in this case:
class FinalFieldExample {
final int x;
int y;
static FinalFieldExample f;
public FinalFieldExample() {
x = 3;
y = 4;
}
static void writer() {
f = new FinalFieldExample();
}
static void reader() {
if (f != null) {
int i = f.x; // guaranteed to see 3
int j = f.y; // could see 0
}
}
}
When it comes to threads, thread1 could see 0 for y or 4 because the constructor needs to be fully initialized for y to be 4 and thread1 could have got to y before the constructor did. But for x it is guaranteed.
Consider the following non-traditional implementation of double-check locking that does not use volatile:
public class ValueProvider {
private static State state = new Initial();
public static Value getValue() {
return state.getValue();
}
private static class Initial implements State {
#Override
public synchronized Value getValue() {
if (state instanceof Initial) {
Value value = new Value();
value.x = 1;
value.y = 2;
state = new Initialized(value);
return value;
} else {
return state.getValue();
}
}
}
private static class Initialized implements State {
private final Value value;
private Initialized(Value value) {
this.value = value;
}
#Override
public Value getValue() {
return value;
}
}
private interface State {
Value getValue();
}
public static final class Value {
private int x;
private int y;
public int getX() {
return x;
}
public int getY() {
return y;
}
}
}
Is this code thread-safe ?
Specifically I am asking about the final field and the guarantees it gives, so the question may be reformulated as is that possible for some thread to get a non-initialized instance of Value ?
UPDATE: removed mention about setters, so that only reads are available after publication
Well, besides the fact that your approach is way too complicated as Bohemian ♦ has pointed out, it could work regarding publication. If two threads access getValue() concurrently, only one thread can enter the synchronized block. The other will either be blocked on the synchronized block or see an instance of Initialized with a correctly initialized value field due to the final field initialization guaranty.
However, it still doesn’t work because the instance of class Value is mutable and your comment // getters and setters indicates that the instance will be mutated after construction. In this case the entire final field initialization guaranty is pointless as the Value class is not thread safe. You might be guarded against seeing the default values for x and y but you will never know what values regarding later-on modifications you will see and the values for (x, y) are not necessarily consistent.
No, this is not thread safe. There is no memory barrier on the read of ValueProvider.state and none at all on Value.
The rule of thumb with Java concurrency is that there needs to be a memory barrier on read and a memory barrier on write.
The only ways to add a memory barrier in Java are:
synchronized
volatile
class initialisation (implicit by the jvm)
atomic
unsafe
For most things Hotspot ignores the final keyword, and prefers to infer it itself. However where final does affect the JMM is to do with class construction and inlining. The reordering rules for final fields are covered in the cookbook that you have already mentioned. It does not mention final classes. The cookbook states:
Loads and Stores of final fields act as "normal" accesses
with respect to locks and volatiles, but impose two additional reordering
1) A store of a final field (inside a constructor and, if the field is a reference, any store that this final can reference, cannot be reordered with a subsequent store
2) The initial load (i.e., the very first encounter by a thread) of a final field cannot be reordered with the initial load of the reference to the object containing the final field.
I have a question regarding the Java "volatile" keyword:
Assume, we have the following Class:
public class BooleanValClass {
private boolean bolVal = false;
public boolean getVal() {
return this.bolVal;
}
public void setVal(boolean val) {
bolVal = val;
}
}
Now, assume a Thread is using this class with a "volatile" keyword:
private volatile BooleanValClass myClass = new BooleanValClass();
Do i have to attach the "volatile" keyword also to the member field "bolVal" of class "BooleanValClass" or is the "volatile" of the object reference some kind of "redirected" to all members of the class "BooleanValClass"?
Thanks,
Tom
Nothing is redirected. myClass is volatile, bolVal is not. Assignments and reads from myClass work as volatile. Assignments/reads to/from bolVal don't.
In Java reading and writing fields of all types except long and double occurs atomically by JVM, and if the field is declared with the VOLATILE modifier, even long and double are become read and written atomically. Atomic garantee, that we get 100% either what was in variable, or what will calculated in variable, nor can there be any intermediate result in the variables.