zoukankan      html  css  js  c++  java
  • java多线程中的volatile和synchronized

    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);
        }
    }

    代码如上,期待输出的是10000,然后,由于count++不是线程安全的,所以输出经常会小于10000.

    为了解决这个问题,增加了volatile关键字。

    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);
        }
    }

    修改之后,还经常输出不是10000的值。

    修改为synchronized形式,代码如下:

    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];
    
    }

    这样修改之后,输出是10000.

    这样是否说明volatile这个关键字完全没用呢?只有synchronized才能保证线程安全?

    在《Java 理论与实践: 正确使用 Volatile 变量》中提到:

    Java™ 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量。这两种机制的提出都是为了实现代码线程的安全性。其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低),而且其使用也更容易出错。Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。

    也就是说,在某些情况下,volitile比synchronized用起来更方便,当然,同步性更差一点。

    详见《Java 理论与实践: 正确使用 Volatile 变量》

    参考:
    http://www.ibm.com/developerworks/cn/java/j-jtp06197.html

  • 相关阅读:
    技术面试问题汇总第005篇:猎豹移动反病毒工程师part5
    技术面试问题汇总第004篇:猎豹移动反病毒工程师part4
    Hexo安装和配置
    hexo从零开始到搭建完整 转
    window下phpstudy的nginx配置虚拟主机
    CentOS Linux搭建SVN服务器
    解决CentOS7关闭/开启防火墙出现Unit iptables.service failed to load: No such file or directory.
    numpy使用
    Linux学习15_CentOS6.5下netcat工具安装教程
    中国天气网七天天气
  • 原文地址:https://www.cnblogs.com/wardensky/p/4153325.html
Copyright © 2011-2022 走看看