在多线程中,提到线程安全、线程同步,我们经常会想到两个关键字:volatile和synchronized,那么这两者有什么区别呢?

1. volatile修饰的变量具有可见性

volatile是变量修饰符,其修饰的变量具有可见性。

可见性也就是说一旦某个线程修改了该被volatile修饰的变量,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,可以立即获取修改之后的值。

在Java中为了加快程序的运行效率,对一些变量的操作通常是在该线程的寄存器或是CPU缓存上进行的,之后才会同步到主存中,而加了volatile修饰符的变量则是直接读写主存。

2. volatile禁止指令重排

volatile可以禁止进行指令重排。

指令重排是指处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证各个语句的执行顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。指令重排序不会影响单个线程的执行,但是会影响到线程并发执行的正确性。

程序执行到volatile修饰变量的读操作或者写操作时,在其前面的操作肯定已经完成,且结果已经对后面的操作可见,在其后面的操作肯定还没有进行。

3. synchronized

synchronized可作用于一段代码或方法,既可以保证可见性,又能够保证原子性。

可见性体现在:通过synchronized或者Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存中。

原子性表现在:要么不执行,要么执行到底。

4.总结

(1)从而我们可以看出volatile虽然具有可见性但是并不能保证原子性。

(2)性能方面,synchronized关键字是防止多个线程同时执行一段代码,就会影响程序执行效率,而volatile关键字在某些情况下性能要优于synchronized。

但是要注意volatile关键字是无法替代synchronized关键字的,因为volatile关键字无法保证操作的原子性。

看下面例子:

public class VolatileTest {public volatile int inc = 0;public void increase() {inc++;}public static void main(String[] args) {final VolatileTest test = new VolatileTest();for(int i=0;i<10;i++){new Thread(){public void run() {for(int j=0;j<1000;j++)test.increase();};}.start();}while(Thread.activeCount()>2)  //保证前面的线程都执行完
            Thread.yield();System.out.println(test.inc);}
}

例子中用new了10个线程,分别去调用1000次increase()方法,每次运行结果都不一致,都是一个小于10000的数字。自增操作不是原子操作,volatile是不能保证原子性的。使用volatile修饰int型变量i,多个线程同时进行i++操作。比如有两个线程A和B对volatile修饰的i进行i++操作,i的初始值是0,A线程执行i++时刚读取了i的值0,就切换到B线程了,B线程(从内存中)读取i的值也为0,然后就切换到A线程继续执行i++操作,完成后i就为1了,接着切换到B线程,因为之前已经读取过了,所以继续执行i++操作,最后的结果i就为1了。同理可以解释为什么每次运行结果都是小于10000的数字。

但是使用synchronized对部分代码进行如下修改,就能保证同一时刻只有一个线程获取锁然后执行同步代码。运行结果必然是10000。

public  int inc = 0;
public synchronized void increase() {  inc++;
}

转载于:https://www.cnblogs.com/rinack/p/8949976.html

JAVA多线程之synchronized和volatile实例讲解相关推荐

  1. Java多线程之Synchronized和Lock的区别

    Java多线程之Synchronized和Lock的区别 目录: 原始构成 使用方法 等待是否可以中断 加锁是否公平 锁绑定多个条件Condition 小结:Lock相比较Synchronized的优 ...

  2. JAVA多线程之Synchronized、wait、notify实例讲解

    一.Synchronized synchronized中文解释是同步,那么什么是同步呢,解释就是程序中用于控制不同线程间操作发生相对顺序的机制,通俗来讲就是2点,第一要有多线程,第二当多个线程同时竞争 ...

  3. Java多线程之Synchronized深入理解

    文章目录 1 Synchronized 1.1 引言 1.2 概念理解 1.2.1 不同锁对象 1.2.2 对象锁和类锁概念区别 1.2.3 同步概念monitorenter&monitore ...

  4. java synchronized 卖票_(二)java多线程之synchronized

    引言 现在,让我们来考虑一个问题,如果要让多个线程来访问同一份数据,会发生什么现象呢?比如12306的火车售票系统,比如银行的存取款系统等等.都可以会出现多线程访问同一个数据的情况.让我们先模拟写一个 ...

  5. Java多线程之Synchronized详解

    一直以来对于Synchronized都比较迷惑,尤其还对于ReentrantLock并不了解他们之间的区别,今天闲来无事,学习了. 1,为什么要使用Synchronized 首先看Synchroniz ...

  6. java多线程之synchronized与lock、wait与notify

    一.synchronized与lock synchronized在java很早的版本就已经有了,它的作用只要是同步代码,解决线程的安全问题,但是随着java的发展,以及开发业务的不断提高,synchr ...

  7. Java多线程之synchronized(二)

    为了解决"非线程安全"带来的问题,上一节中使用的办法是用关键字synchronized修饰多个线程可能同时访问到的方法,但是这样写是存在一定的弊端的,比如线程A调用一个用synch ...

  8. JAVA多线程之wait/notify

    本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...

  9. Java多线程之volatile详解

    Java多线程之volatile详解 目录: 什么是volatile? JMM内存模型之可见性 volatile三大特性之一:保证可见性 volatile三大特性之二:不保证原子性 volatile三 ...

  10. Java多线程之CAS深入解析

    Java多线程之CAS深入解析 目录: CAS是什么 CAS底层原理Unsafe深入解析 CAS缺点 引子:蚂蚁花呗一面:讲一讲AtomicInteger,为什么要用CAS而不是synchronize ...

最新文章

  1. 简单工厂模式(StaticFactoryMethod)
  2. 智能安防市场的痛点是什么?
  3. oracle 删除用户 递归,ORACLE递归查询遍历详解
  4. 对contentoffset的理解
  5. DolphinScheduler 调度系统
  6. 毕设之 yolo5 航空影像飞行器检测
  7. 聊斋志异读后感 [20180818]
  8. 抢不到回家的票,还真不是12306技术不行
  9. PS图片去水印的方法
  10. 软件开发平台之争:NET VS Java,谁是更好的选择?
  11. 什么是tv域名?.tv域名不能实名吗?
  12. 《棒球英豪》:青春球场·棒球1号位
  13. k8s存储之Volumes卷类型
  14. 「C#」异步编程玩法笔记-WinForm中的常见问题
  15. 【web】React-hooks
  16. Effective Java读书笔记一(Java Tips.Day.1)
  17. chrome linux依赖包,[WebDriver]Linux/Docker下安装Chrome浏览器和ChromeDriver
  18. 力学笃行系列之List自定义排序
  19. P2PNet(代码阅读笔记)
  20. 齐鲁工业大学计算机应用技术研究生专业,2017年齐鲁工业大学计算机应用技术研究所872数据结构考研题库...

热门文章

  1. 华为开始销售预装深度 Linux 的笔记本电脑
  2. 雷军:程序员如何成功创业?
  3. Google 发布首款微信小程序,各种灵魂画作出没!
  4. 如何提升人脸识别的精度_宝比万像人脸识别:健身房人脸识别门禁系统如何助力健身房管理?...
  5. nosql数据库之Redis集群
  6. Linux进阶之Linux中的标准输入输出
  7. 域名有www与没有www有什么区别?
  8. BZOJ 3744: Gty的妹子序列 [分块]
  9. 机器学习-斯坦福:学习笔记1-机器学习的动机与应用
  10. 另类的JS常见函数应用