This article analyzes the usage of volatile and synchronized in Java multi-threading with examples. Share it with everyone for your reference. The specific implementation method is as follows:
Copy the code as follows: package com.chzhao;
public class Volatiletest extends Thread {
private static int count = 0;
public void run() {
count++;
}
public static void main(String[] args) {
Thread threads[] = new Thread[10000];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Volatiletest();
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count);
}
}
The code is as above. The expected output is 10000. However, since count++ is not thread-safe, the output will often be less than 10000.
To solve this problem, the volatile keyword was added.
Copy the code as follows: package com.chzhao;
public class Volatiletest extends Thread {
private volatile static int count = 0;
public void run() {
count++;
}
public static void main(String[] args) {
Thread threads[] = new Thread[10000];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Volatiletest();
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count);
}
}
After modification, values other than 10000 are often output.
Modify it to synchronized form, the code is as follows:
Copy the code as follows: package com.chzhao;
public class SynchronizedTest extends Thread {
private static int count = 0;
public void run() {
synchronized (LockClass.lock) {
count++;
}
}
public static void main(String[] args) {
Thread threads[] = new Thread[10000];
for (int i = 0; i < threads.length; i++) {
threads[i] = new SynchronizedTest();
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count);
}
}
Copy the code as follows: package com.chzhao;
public class LockClass {
public static byte[] lock = new byte[0];
}
After this modification, the output is 10000.
Does this mean that the volatile keyword is completely useless? Only synchronized can guarantee thread safety?
illustrate:
The Java language contains two inherent synchronization mechanisms: synchronized blocks (or methods) and volatile variables. Both mechanisms are proposed to achieve code thread safety. Volatile variables are less synchronized (but sometimes simpler and less expensive), and their use is also more error-prone. Volatile variables in the Java language can be thought of as "less synchronized"; compared to synchronized blocks, volatile variables require less coding and have less runtime overhead, but they can achieve Functionality is only part of synchronized.
In other words, in some cases, volitile is more convenient to use than synchronized, but of course, the synchronization is worse.
I hope this article will be helpful to everyone’s Java programming.