Volatile VS Static in Java

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



Leave a reply



Submit