Home  >  Article  >  Java  >  Usage analysis of volatile and synchronized in java multithreading

Usage analysis of volatile and synchronized in java multithreading

高洛峰
高洛峰Original
2017-01-05 16:02:511776browse

The example of this article analyzes the usage of volatile and synchronized in java multi-threading. Share it with everyone for your reference. The specific implementation method is 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. Then, since count++ is not thread-safe, the output will often be less than 10000.

In order to solve this problem, an additional volatile keyword.

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 to synchronized form, the code is 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);
    }
}
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 ensure thread safety?

Note:

The Java language contains two intrinsic 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.

For more articles related to the usage analysis of volatile and synchronized in java multi-threading, please pay attention to the PHP Chinese website!


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn