Volatile vs Static in Java
Declaring a static variable in Java, means that there will be only one copy, no matter how many objects of the class are created. The variable will be accessible even with no Objects
created at all. However, threads may have locally cached values of it.
When a variable is volatile and not static, there will be one variable for each Object
. So, on the surface it seems there is no difference from a normal variable but totally different from static. However, even with Object
fields, a thread may cache a variable value locally.
This means that if two threads update a variable of the same Object concurrently, and the variable is not declared volatile, there could be a case in which one of the thread has in cache an old value.
Even if you access a static value through multiple threads, each thread can have its local cached copy! To avoid this you can declare the variable as static volatile and this will force the thread to read each time the global value.
However, volatile is not a substitute for proper synchronisation!
For instance:
private static volatile int counter = 0;
private void concurrentMethodWrong() {
counter = counter + 5;
//do something
counter = counter - 5;
}
Executing concurrentMethodWrong
concurrently many times may lead to a final value of counter different from zero!
To solve the problem, you have to implement a lock:
private static final Object counterLock = new Object();
private static volatile int counter = 0;
private void concurrentMethodRight() {
synchronized (counterLock) {
counter = counter + 5;
}
//do something
synchronized (counterLock) {
counter = counter - 5;
}
}
Or use the AtomicInteger
class.
Can volatile variable be defined as static in java?
To expand on Michael's comment.
static
simply means not associated with an instance of the containing class.
volatile
simply means that the value may be changed by other threads without warning.
So your question boils down to "can a field not associated with an instance of the containing class be changed by another thread without warning?"
As Michael pointed out, the answer to that question is yes. Instance association is orthogonal to concurrent modification.
static volatile' vs. 'static' vs. 'volatile' in C
static - in this case makes the variable visible only inside the current file
volatile - it is information for the compiler that the object can be changed by something outside the normal execution path (for example, the interrupt routine) and guarantees that the variable will be read before any use and written after every change. volatile (which is a very common misunderstanding) does not guarantee anything else - no atomicity, no cache coherency, etc., etc.
Static variable vs Volatile
The problem is that the ++ is not atomic. The code should use AtomicInteger
instead. With the static
variable, both threads are trying to update the same value and the ++ is actually 3 operations: get, +1, and store. This means that there is a race condition between both of the threads and they are overwriting each other.
Why thread 2 is not reading the updated value? If it has to be made static , whats the use of volatile?
static
and volatile
do different things. static
makes the field associated with the class as opposed to the object instance. volatile
forces any read or write of the field to cross a memory barrier. This allows multiple threads to read and update a common field but this does not protected you from multiple operations. If you make the variable not be static then you would not need the volatile
since each thread would be working with it's own instance of the field.
You should use AtomicInteger
. This wraps a volatile int
but also provides special handling of increment operations:
private static AtomicInteger testValue = new AtomicInteger(1);
...
testValue.incrementAndGet();
Can someone give link to a good example of volatile where that variable is not declare static.
You would need a volatile
on a non-static field when it was shared by multiple threads. For example, if you moved the testValue
up into the VolatileExample
class and then passed the same instance of the VolatileExample
class into both threads so they could access testValue
.
What is the differences between volatile and static keyword?
I think you've misunderstood both static
and volatile
.
static
is just about having a single field across the whole type. It has nothing to do with threads - it's just about whether there's one field for the type (static
) or one field for each instance of the type (non-static
).
volatile
is just about what guarantees there are around when changes made by one thread are visible in other threads. This has nothing to do with whether the field is static or not. From section 8.3.1.4 of the JLS:
The Java programming language allows threads to access shared variables (§17.1). As a rule, to ensure that shared variables are consistently and reliably updated, a thread should ensure that it has exclusive use of such variables by obtaining a lock that, conventionally, enforces mutual exclusion for those shared variables.
The Java programming language provides a second mechanism, volatile fields, that is more convenient than locking for some purposes.
A field may be declared volatile, in which case the Java Memory Model ensures that all threads see a consistent value for the variable (§17.4).
(Section 17.4 has a lot more detail.)
Can any one tell me the difference between volatile and static in java
The volatile
and static
keywords have completely different meanings.
static
means the field (I'm assuming you're talking about fields, since methods can't be volatile
) does not belong to an individual objects, but to the class in which it is defined, and there is only one of it, rather than a different one for each instance of the class.
volatile
is only relevant if you have multiple threads accessing a field. In that case, it prevents the content of the field from being cached by individual threads. If a non-volatile
field is set in one thread and read in another, and this does not happen in a synchronized
block or method, the second thread could see the "old" value of the field for an arbitrarily long time.
Volatile keyword without static not working as expected
Your bug is due to the fact that if you remove the static
keyword from the field i
, you will have one different field i
per instance of PrintOddAndEven
so here as you have 2
instances, you have 2 different fields i
such that the Even
thread will loop forever as its i
is never modified and the Odd
thread waits forever for the same reason. When you declare the field as static
, the threads share the same field i
such that you don't face your bug.
You should create a dedicated class that will hold your counter and use an instance of it as object monitor that you will share between the PrintOddAndEven
instances, as next:
public class MyClass {
volatile int i = 1;
}
public class PrintOddAndEven extends Thread {
MyClass lock;
PrintOddAndEven(MyClass lock) {
this.lock = lock;
}
public static void main(String[] args) throws Exception {
MyClass obj = new MyClass();
PrintOddAndEven odd = new PrintOddAndEven(obj);
PrintOddAndEven even = new PrintOddAndEven(obj);
odd.setName("Odd");
even.setName("Even");
odd.start();
even.start();
}
@Override
public void run() {
while (lock.i <= 10) {
if (lock.i % 2 == 0 && Thread.currentThread().getName().equals("Even")) {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " - " + lock.i);
lock.i++;
lock.notify();
}
}
if (lock.i % 2 == 1 && Thread.currentThread().getName().equals("Odd")) {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " - " + lock.i);
lock.i++;
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
If you have only a counter, you could also consider using an instance of class AtomicInteger
as counter and object monitor. The code will be the same as above except that you will create an instance using new AtomicInteger(1)
to initialize the counter to 1
and then use get()
to get the current value and incrementAndGet()
to increment the counter.
Should I synchronize a static volatile variable?
You'd definitely need some sort of locking to ensure that only one thread writes to the field. Regardless of the volatility, two threads can both "see" that obj
is null, and then both start initializing with your current code.
Personally I'd take one of three options:
Initialize on class load (knowing that that will be lazy, but not as lazy as waiting until
getMyObj
is first called):private static final MyObj obj = new MyObj();
Use unconditional locking:
private static MyObj obj;
private static final Object objLock = new Object();
public static MyObj getMyObj() {
synchronized(objLock) {
if (obj == null) {
obj = new MyObj();
}
return obj;
}
}Use a nested class for laziness that way:
public static MyObj getMyObj() {
return MyObjHolder.obj;
}
private static class MyObjHolder {
static final MyObj obj = new MyObj();
}
Related Topics
Simpledateformat Parsing Date with 'Z' Literal
Preferred Java Way to Ping an Http Url for Availability
What Is Short Circuiting and How Is It Used When Programming in Java
Make Maven to Copy Dependencies into Target/Lib
Gson Serialize a List of Polymorphic Objects
Loading Images from Jars for Swing HTML
Jaxb: How to Marshall Map into <Key>Value</Key>
What Is the Cost of Calling Array.Length
How to Print an Image on a Bluetooth Printer in Android
Java Byte Array to String to Byte Array
Error: Selection Does Not Contain a Main Type
How to Return a JSON Object from a Java Servlet
Why Do These Two Multiplication Operations Give Different Results
Why Would a Static Nested Interface Be Used in Java
Convert an Array of Primitive Longs into a List of Longs
Jsp - What Is Wrong with Scriptlets, and What to Use Instead
Arithmeticexception: "Non-Terminating Decimal Expansion; No Exact Representable Decimal Result"