Are the primitive data types like int
& short
thread-safe in Java? I have executed the following code and couldn't see expected result 500 some times.
public class SampleThree extends Thread
{
static long wakeUpTime = System.currentTimeMillis() + (1000*20);
static int inT;
public static void main(String args[])
{
System.out.println("initial:" + inT);
for(int i=0; i<500; i++)
new SampleThree().start();
try {
Thread.sleep(wakeUpTime - System.currentTimeMillis() + (1000*30));
System.out.println("o/p:" + inT);
}
catch(Exception e){
e.printStackTrace();
}
}
public void run()
{
try {
long s = wakeUpTime - System.currentTimeMillis();
System.out.println("will sleep ms: " + s);
Thread.sleep(s);
inT++; // System.out.println(inT);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
Here concurrently 500 thread will update the int variable inT
. Main thread after waiting for concurrent update to be completed, prints inT
value.
Find similar example here
There are three ways in which they're not safe:
long
anddouble
aren't even guaranteed to be updated atomically (you could see half of a write from a different thread)Use
AtomicInteger
etc for thread-safe operations.To read/write of a value in a multiple thread environment, the program should have proper synchronize or lock to prevent data races. It has nothing to do with which data type to access. In an ideal world, we should share nothing or only share immutable objects, which is always thread safe.
In theory, It is even not ensured to be atomic for long/double according to https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.7 HOWEVER, the implementation tends to atomic, the following code print out nothing with or without volatile keyword in my environment(64bit ubuntu 18.04, Intel 64bit CPU, Oracle JDK 8), so it is atomic in this situation, which I guess apply to all Intel/AMD 64 CPU. We could do the same for double as well, although it is a little tricky to construct double value with certain property to check.
Primitive types are not thread safe. Check this tutorial.
I would suggest using classes in java.util.concurrent.atomic. They are designed for thread-safety and in some cases the JVM can take advantage of hardware features to optimize.