I am getting the warning in sonar at line synchronized (new Integer(count)) as
Synchronize on a new "Object" instead.
public class PRMDataTransferHelper {
/** static variable to keep count */
private static int count = 0;
private static void done() {
synchronized (new Integer(count)) {
count--;
if (0 == count) {
cleanUp();
}
}
return;
}
}
There are two problems here:
As Sonar states, you shouldn't synchronize on a primitive wrapper (i.e. Integer, Long, Boolean, etc.) since these can be created by autoboxing, and Sonar assumes that this is risky. It is risky because a lock object used in a synchronized statement should be constant among all threads that are to be synchronized. Any dynamic object that may be re-used in the program logic can easily lead to failed synchronization. Therefore, it is best practise to instantiate Object and create a special lock object that is used for synchronization only.
You are using new Integer(count), i.e. whenever the synchronized block is entered, a new instance of integer is created. This means that each thread will see its own version of a lock object, and thus the block will not be synchronized between threads at all. In order to achieve synchronization, you need to re-use a lock object shared by all threads.
In your case, having a static variable such as
private static Object lock=new Object();
and using this one in synchronized(lock) would ensure that all threads are indeed synchronized at the beginning of the block.
Related
class A {
private static BigInteger staticCode = BigInteger.ZERO;
private BigInteger code;
public A() {
synchronized(staticCode) {
staticCode = staticCode.plus(BigInteger.ONE);
code = staticCode;
}
}
}
I'm not an expert in concurrency by any means. Could someone explain to me why the class provided above isn't thread safe?
What are the situations that can cause a race condition? My thought process is that if we create 10 instances of this class, every instance will synchronize on a different value of staticCode and that's why it's thread safe, but I was told that it wasn't. But why?
I know that we can synchronize on .class and it will definitely be thread safe, but I still want to understand this particular situation.
Does synchronizing on the static field that you are modifying make your code thread safe?
No, because you're reassigning it. (*)
As soon as that reassignment has taken place, you've effectively lost the mutual exclusion on access to the staticCode field.
Any thread which is already waiting at the synchronized block before the assignment will continue to wait.
Any thread which arrives at the synchronized block after the reassignment but before the reassigning thread has left the block will attempt to synchronize on the new value of staticCode.
A more subtle point than the fact you don't have mutual exclusion is that you also lose the happens-before between the end of the synchronized block and the start of the next execution. This means that you don't have guaranteed visibility of the updated value, so you can potentially generate multiple instances of A with the same code.
It's a bad idea to synchronize on a non-final member. If you don't want to synchronize on A.class, you can define an auxilliary member on which to synchronized:
class A {
private static final Object lock = new Object();
private static BigInteger staticCode = BigInteger.ZERO;
public A() {
synchronized (lock) {
staticCode = ...
}
}
}
This preserves the mutability of staticCode, but allows correct mutual exclusion.
However, an Atomic* class would be far easier because you avoid the need to synchronize (e.g. AtomicInteger or AtomicLong - but if you really think you're going to have more than 2^63 things, you can use an AtomicReference<BigInteger>):
class A {
private static final Object lock = new Object();
private static AtomicReference<BigInteger> staticCode = new AtomicReference<>(BigInteger.ZERO);
public A() {
BigInteger code;
do {
code = staticCode.get();
} while (!staticCode.compareAndSet(code, code.add(BigInteger.ONE)));
this.code = code;
// Even easier with AtomicInteger/Long:
// this.code = BigInteger.valueOf(staticCode.incrementAndGet());
}
}
(*) But anyway, dispense with the notion that synchronizing automatically makes something thread safe. For one thing, you need to define precisely what you mean by "thread safe"; but then, you need to understand what synchronization actually provides for you, in order to evaluate whether those things satisfy your thread safety requirements.
I guess the main point I was missing here is that we synchronize on objects, not references to objects.
Consider a situation where I synchronize on BigInteger.ZERO, and then enter the synchronized block.
When the value of staticCode has changed and become BigInteger.ONE, this block still continues to be synchronized on BigInteger.ZERO. Meanwhile another thread is already synchronized on BigInteger.ONE, before we even had a change to assign BigInteger.ONE to code. That second thread could bump staticCode to the value of 2, and now both threads are before the second assignment, but the value of staticCode is 2, so they can both assign the same value of staticCode to 2 different instances of the class.
If we have 2 classes that operate on the same object under different threads and we want to avoid race conditions, we'll have to use synchronized blocks with the same monitor like in the example below:
class A {
private DataObject mData; // will be used as monitor
// thread 3
public setObject(DataObject object) {
mData = object;
}
// thread 1
void operateOnData() {
synchronized(mData) {
mData.doSomething();
.....
mData.doSomethingElse();
}
}
}
class B {
private DataObject mData; // will be used as monitor
// thread 3
public setObject(DataObject object) {
mData = object;
}
// thread 2
void processData() {
synchronized(mData) {
mData.foo();
....
mData.bar();
}
}
}
The object we'll operate on, will be set by calling setObject() and it will not change afterwards. We'll use the object as a monitor. However, intelliJ will warn about synchronization on a non-final field.
In this particular scenario, is the non-local field an acceptable solution?
Another problem with the above approach is that it is not guaranteed that the monitor (mData) will be observed by thread 1 or thread 2 after it is set by thread 3, because a "happens-before" relationship hasn't been established between setting and reading the monitor. It could be still observed as null by thread 1 for example. Is my speculation correct?
Regarding possible solutions, making the DataObject thread-safe is not an option. Setting the monitor in the constructor of the classes and declaring it final can work.
EDIT Semantically, the mutual exclusion needed is related to the DataObject. This is the reason that I don't want to have a secondary monitor. One solution would be to add lock() and unlock() methods on DataObject that need to be called before working on it. Internally they would use a Lock Object. So, the operateOnData() method becomes:
void operateOnData() {
mData.lock()
mData.doSomething();
.....
mData.doSomethingElse();
mData.unlock();
}
You may create a wrapper
class Wrapper
{
DataObject mData;
synchronized public setObject(DataObject mData)
{
if(this.mData!=null) throw ..."already set"
this.mData = mData;
}
synchronized public void doSomething()
{
if(mData==null) throw ..."not set"
mData.doSomething();
}
A wrapper object is created and passed to A and B
class A
{
private Wrapper wrapper; // set by constructor
// thread 1
operateOnData()
{
wrapper.doSomething();
}
Thread 3 also has a reference to the wrapper; it calls setObject() when it's available.
Some platforms provide explicit memory-barrier primitives which will ensure that if one thread writes to a field and then does a write barrier, any thread which has never examined the object in question can be guaranteed to see the effect of that write. Unfortunately, as of the last time I asked such a question, Cheapest way of establishing happens-before with non-final field, the only time Java could offer any guarantees of threading semantics without requiring any special action on behalf of a reading thread was by using final fields. Java guarantees that any references made to an object through a final field will see any stores which were performed to final or non-fields of that object before the reference was stored in the final field but that relationship is not transitive. Thus, given
class c1 { public final c2 f;
public c1(c2 ff) { f=ff; }
}
class c2 { public int[] arr; }
class c3 { public static c1 r; public static c2 f; }
If the only thing that ever writes to c3 is a thread which performs the code:
c2 cc = new c2();
cc.arr = new int[1];
cc.arr[0] = 1234;
c3.r = new c1(cc);
c3.f = c3.r.f;
a second thread performs:
int i1=-1;
if (c3.r != null) i1=c3.r.f.arr[0];
and a third thread performs:
int i2=-1;
if (c3.f != null) i2=c3.f.arr[0];
The Java standard guarantees that the second thread will, if the if condition yields true, set i1 to 1234. The third thread, however, might possibly see a non-null value for c3.f and yet see a null value for c3.arr or see zero in c3.f.arr[0]. Even though the value stored into c3.f had been read from c3.r.f and anything that reads the final reference c3.r.f is required to see any changes made to that object identified thereby before the reference c3.r.f was written, nothing in the Java Standard would forbid the JIT from rearranging the first thread's code as:
c2 cc = new c2();
c3.f = cc;
cc.arr = new int[1];
cc.arr[0] = 1234;
c3.r = new c1(cc);
Such a rewrite wouldn't affect the second thread, but could wreak havoc with the third.
A simple solution is to just define a public static final object to use as the lock. Declare it like this:
/**Used to sync access to the {#link #mData} field*/
public static final Object mDataLock = new Object();
Then in the program synchronize on mDataLock instead of mData.
This is very useful, because in the future someone may change mData such that it's value does change then your code would have a slew of weird threading bugs.
This method of synchronization removes that possibility. It also is really low cost.
Also having the lock be static means that all instances of the class share a single lock. In this case, that seems like what you want.
Note that if you have many instances of these classes, this could become a bottleneck. Since all of the instances are now sharing a lock, only a single instance can change any mData at a single time. All other instances have to wait.
In general, I think something like a wrapper for the data you want to synchronize is a better approach, but I think this will work.
This is especially true if you have multiple concurrent instances of these classes.
I have a counter and multiple threads access the getCount method. The code is like the following:
public class ThreadSafeMethod {
public static int counter = 0;
public static int getCount() {
return counter++;
}
}
Is the method thread safe? My understanding is that because counter++ is not atomatic, it is not safe. Then how to make it safe? If we add synchronized keyword, what object will be synchronized?
You are correct in your analysis when you say that it's not thread safe because the operation is not atomic. The retrieval of the value and the increment are not thread safe. Multiple calls to this method (whether it has parameters or not) access the same non-local variable.
Adding synchronized to this method makes it thread-safe. When adding to a static method, then the Class object is the object which is locked.
An alternative to making it thread-safe is to replace the int with an AtomicInteger, which has its own atomic getAndIncrement method.
No, a parameter-less method is not inherently thread-safe - the lack of parameters makes no difference in this example.
The read from (and write to) the counter variable is not guaranteed to be either atomic or consistent between threads.
The simplest change is to simply make the method synchronized:
public static synchronized int getCount() {
return counter++;
}
(The simplest is not always the "best" or "correct", but it will be sufficient here, assuming that no other code touches the public counter variable.)
See this answer for how a synchronization of a static method works - as can be imagined, it is the Class itself that is used as the monitor.
Using the synchronised keyword on the static function will 'lock' the function to one thread at a time to ensure that two threads can not mess with the same variable. With what you propose, I believe anything that gets accessed or modified in that function will be thread safe.
Just as you say the counter++ operation is non atomic so giving multiple threads access at once will result in undefined behaviour. In thread safety, the issue is almost always having synchronized access to shared resources such as static variables.
The lock which a thread acquires when declaring the method synchronized belongs to that class. Say we had two methods in a class
public synchronized void foo() {...}
public synchronized void bar() {...}
If one thread enters foo() it acquires the lock for the class, and any other thread trying to access foo() OR bar() will block until the first thread has finished. To overcome this, we can lock on seperate objects within the methods.
// Declare 2 objects to use as locks within the class
private Object fooLock = new Object();
private Objecy barLock = new Object();
// lock on these objects within the method bodies
public void foo {
synchronized(fooLock) { /* do foo stuff */ }
}
public void bar() {
synchronized(barLock) {/* do bar stuff */}
}
Now 2 threads can access the foo() and bar() simultaneously.
There's a lot of material on the web on Thread safety, I'd recommend this set of tutorials if yo want to know more about multithreading with locks / executor services and stuff.
I have a code like the one below where an object is shared among two threads (the main thread and the Monitor thread). Do I have to declare MyObject globally and make it volatile to ensure it will be pushed to memory? Otherwise the if statement can print "Not null" if MyObject is only locally accessed by the thread and is not declared volatile, right?
public static void main(String[] args) {
MyObject obj = MyObjectFactory.createObject();
new Monitor(obj).start();
Thread.sleep(500);
if(obj == null)
System.out.println("Null");
else
System.out.println("Not null");
}
public void doSomethingWithObject(MyObject obj) {
obj = null;
}
private class Monitor extends Thread {
public Monitor(MyObject obj) {
this.obj=obj;
}
public void run() {
doSomethingWithObject(obj);
}
}
Note: The code example may not compile since I wrote it myself here on Stackoverflow. Consider it as a mix of pseudo code and real code.
The instance is shared but the references to it are not. Example:
String a = "hello";
String b = a;
b = null; // doesn't affect a
a and b are references to the same instance; changing one reference has no effect on the instance or any other references to the same instance.
So if you want to share state between threads, you will have to create a field inside MyObject which has to be volatile:
class MyObject { public volatile int shared; }
public void doSomethingWithObject(MyObject obj) {
obj.shared = 1; // main() can see this
}
Note that volatile just works for some types (references and all primitives except long). Since this is easy to get wrong, you should have a look at types in java.util.concurrent.atomic.
[EDIT] What I said above isn't correct. Instead, using volatile with long works as expected for Java 5 and better. This is the only way to ensure atomic read/writes for this type. See this question for references: Is there any point in using a volatile long?
Kudos go to Affe for pointing that out. Thanks.
You would rather have to synchronize on the object to ensure it will be set to null before the if check. Setting it to volatile only means changes will be "seen" immediately by other threads, but it is very likely that the if check will be executed before the doSomethingWithObject call.
If you want your object to go through a read-update-write scheme atomically, volatile won't cut it. You have to use synchronisation.
Volatility will ensure that the variable will not be cached in the current thread but it will not protect the variable from simultaneous updates, with the potential for the variable becoming something unexpected.
IBM's developerWorks has a useful article on the subject.
Your example consists only one thread, Monitor, which is created and run in main().
"make it volatile to ensure it will be pushed to memory?" - on the contrary, when you declare a variable as volatile - it ensures that it's NOT being "pushed" (cached) to the thread-local memory, cause there might be other threads that will change the value of the variable.
In order to make sure you print the correct value of a variable you should synchronize the method doSomethingWithObject (change the signature of the method to):
public synchronized void doSomethingWithObject(MyObject obj)
or create synchronized blocks around:
obj = null;
and
this.obj=obj;
I am confused about synchronizing an instance method and a static method.
I want to write a thread safe class as follow :
public class safe {
private final static ConcurrentLinkedQueue<Object> objectList=
new ConcurrentLinkedQueue<Object>();
/**
* retrieves the head of the object and prints it
*/
public synchronized static void getHeadObject() {
System.out.println(objectList.peek().toString());
}
/**
* creates a new object and stores in the list.
*/
public synchronized void addObject() {
Object obj=new Object();
objectList.add(obj);
}
}
Synchronizing on a static method will lock on safe.class lock and synchronizing on a instance method will lock on this .and hence an inconsistent state will be reached.
If I want to achieve a consistent state for a below code snippet how can that be achieved?
First, ConcurrentLinkedQueue does not require explicit synchronization. See this answer.
Second, you always can synchronize object you are accessing:
public class safe {
private final static ConcurrentLinkedQueue<Object> objectList=
new ConcurrentLinkedQueue<Object>();
/**
* retrieves the head of the object and prints it
*/
public static void getHeadObject() {
synchronized(objectList){
System.out.println(objectList.peek().toString());
}
}
/**
* creates a new object and stores in the list.
*/
public void addObject() {
Object obj=new Object();
synchronized(objectList){
objectList.add(obj);
}
}
}
EDIT: I'm assuming you meant Queue<Object> objectList instead of ConcurrentLinkedQueue<Object> objectList. ConcurrentLinkedQueue<Object> already does all of your thread safety for you, meaning you can call objectList.peek() all you want without worrying about race conditions. This is great if you're developing multi-threaded programs but not so great for learning about thread safety.
Your methods need not be synchronized, assuming you have one thread operating on one instance of the object at a time, but however if you need to have multiple instances of the class that all refer to the same static class variable, you need to synchronized over the class variable like so:
public static void getHeadObject() {
synchronized(safe.objectList) {
System.out.println(objectList.peek().toString());
}
}
This locks the objectList and does not allow it to be read or written to in any other thread as soon as the program is inside the synchronization block. Do the same for all other methods to be synchronized.
NOTE:
However, since you are doing only one simple get operation List.peek(), you really don't need to synchronize over the objectList since in a race condition, it'll get either one value of the List or another. The problem with race conditions is when multiple complex read/write operations are performed, with the value changing in between them.
For example, if you had a class PairInt with a PairInt.x and PairInt.y fields, with the constraint that x = 2y, and you wanted to do
System.out.println(myIntPair.x.toString() + ", " + myIntPair.y.toString());
and another thread was updating the value of x and y at the same time,
myIntPair.y = y + 3;
myIntPair.x = 2 * y;
And the write thread modified myIntPair in between your read thread's myIntPair.x.toString() and myIntPair.y.toString() you might get an output that looks like (10, 8), which means if you are operating on the assumption that x == 2 * y could crash your program.
In that case, your read needs to use a synchronized, but for more simpler things like peek() on a simple object that is being added or deleted, not modified while in the queue, the synchronized can, in most cases be dropped. In fact, for string, int, bool, and the like, the synchronized condition for a simple read should be dropped.
However, writes should always be synchronized on operations that are not explicitly thread safe, i.e. already handled by java. And as soon as you acquire more than one resource, or require that your resource stay the same throughout the operation as you do multiple lines of logic to it, then you MUST USE synchronized
A few comments:
Java conventions:
class names should be in CamelCase (i.e. call your class Safe, not safe)
static comes before synchronized in methods declaration
static comes before final in fields declaration
as others have already said, ConcurrentLinkedQueue is already thread safe, so there is no need for synchronization in the example you give.
mixing static and non static methods the way you do looks weird.
assuming that your actual use case is more complicated and you need a method to run atomic operations, then your code does not work, as you pointed out, because the 2 synchronized methods don't synchronize on the same monitor:
public static synchronized getHeadObject(){} //monitor = Safe.class
public static synchronized addObject(){} //monitor = this
So to answer your specific question, you could use a separate static object as a lock:
public class Safe {
private static final ConcurrentLinkedQueue<Object> objectList =
new ConcurrentLinkedQueue<Object>();
// lock must be used to synchronize all the operations on objectList
private static final Object lock = new Object();
/**
* retrieves the head of the object and prints it
*/
public static void getHeadObject() {
synchronized (lock) {
System.out.println(objectList.peek().toString());
}
}
/**
* creates a new object and stores in the list.
*/
public void addObject() {
synchronized (lock) {
Object obj = new Object();
objectList.add(obj);
}
}
}