volatile和synchronized的区别

2024-05-21 16:23:59 浏览数 (4)

volatile和synchronized的区别

  • 原子性:不可分割,线程A在执行任务的时候,不能被打扰,也不能被分割,要么同时成功,要么同时失败。
  • 指令重排: 是指在程序执行过程中,为了性能考虑,编译器和CPU可能会对指令重新排序。
  • 可见性:简单来说就是一个线程修改了变量,其他线程可以立即知道。

synchronized工作原理:

  • 进入 synchronized 块的内存语义是把在 synchronized 块内使用的变量从线程的工作内存中清除,从主内存中读取;
  • 退出 synchronized 块的内存语义是把在 synchronized 块内对共享变量的修改刷新到主内存中。

volatile工作原理:

  • 线程在【读取】共享变量时,会先清空工作内存变量值,再从主内存获取最新值;
  • 线程在【写入】共享变量时,不会把值缓存在工作内存,而是会把值刷新回主内存。
  • volatile 用于多线程环境下的单次操作(单次读或者单次写)。

总结

  1. volatile是变量修饰符,而synchronized则作用于一段代码或方法
  2. volatile只是在线程内存和主内存间同步某个变量的值;而synchronized通过锁定和解锁某个监视器同步所有变量的值,显然synchronized要比volatile消耗更多资源。
  3. volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
  4. volatile保证数据的可见性,但不能保证原子性;而synchronized可以保证原子性,也可以间接保证可见性,因为它会将私有内存中和公共内存中的数据做同步。volatile关键字解决的是内存可见性的问题,会使得所有对volatile变量的读写都会直接刷到主存,即保证了变量的可见性。使用volatile关键字仅能实现对原始变量(如boolean、 short 、int 、long等)操作的原子性,但需要特别注意, volatile不能保证复合操作的原子性,即使只是i ,实际上也是由多个原子操作组成:read i; inc; write i,假如多个线程同时执行i volatile只能保证他们操作的i是同一块内存,但依然可能出现写入脏数据的情况。
  5. volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化。

0 人点赞