Java – static variable vs volatile

I'm just asking questions from a thread perspective... I may have answered many times, but please help me understand this

Refer to the post volatile vs static in Java here

Ask that a static variable value will also be a value for all threads, so why should we choose volatile? I found the following examples:

public class VolatileExample {  
public static void main(String args[]) {  
    new ExampleThread("Thread 1 ").start();  
    new ExampleThread("Thread 2 ").start();  
}  

}  
class ExampleThread extends Thread {  
private static volatile int testValue = 1;  
public ExampleThread(String str){  
    super(str);  
}  
public void run() {  
    for (int i = 0; i < 3; i++) {  
        try {  
            System.out.println(getName() + " : "+i);  
            if (getName().compareTo("Thread 1 ") == 0)  
            {  
                testValue++;  
                System.out.println( "Test Value T1: " + testValue);  
            }  
            if (getName().compareTo("Thread 2 ") == 0)  
            {  
                System.out.println( "Test Value T2: " + testValue);  
            }                 
            Thread.sleep(1000);  
        } catch (InterruptedException exception) {  
            exception.printStackTrace();  
          }  
       }  
       }  
       }

Output:

Thread 1 : 0
Test Value T1: 2
Thread 2 : 0
Test Value T2: 2
Thread 1 : 1
Test Value T1: 3
Thread 2 : 1
Test Value T2: 3
Thread 1 : 2
Test Value T1: 4
Thread 2 : 2
Test Value T2: 4

If I delete static from testvalue, the result is:

Thread 1 : 0
Test Value T1: 2
Thread 2 : 0
Test Value T2: 1
Thread 1 : 1
Test Value T1: 3
Thread 2 : 1
Test Value T2: 1
Thread 1 : 2
Test Value T1: 4
Thread 2 : 2
Test Value T2: 1

Why did thread 2 not read the updated value? If it has to be static, what is the use of volatile?

Someone can link to a good example of volatile, where the variable is not declared static

thank you

Solution

The problem is that it is not atomic The code should use atomicinteger Using static variables, both threads try to update the same value, which is actually three operations: get, 1 and store This means that there are competing conditions between the two threads and they cover each other

Static and changeable do different things Static makes the fields associated with this class correspond to object instances Volatile forces any field to be read or written across the memory barrier This allows multiple threads to read and update common fields, but it does not protect you from multiple operations If you make variables not static, you don't need volatile because each thread uses its own field instance

You should use atomicinteger This wraps a volatile int, but also provides special handling for incremental operations:

private static AtomicInteger testValue = new AtomicInteger(1);
...
testValue.incrementAndGet();

When multiple threads share non static fields, you need a volatile For example, if you move testvalue into the volatileexample class, and then pass the same instance of the volatileexample class to two threads so that they can access testvalue

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>