Skip to content

2019-05-16:synchronized和volatile关键字的区别? #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
MoJieBlog opened this issue May 16, 2019 · 7 comments
Open

2019-05-16:synchronized和volatile关键字的区别? #55

MoJieBlog opened this issue May 16, 2019 · 7 comments
Labels

Comments

@MoJieBlog
Copy link
Collaborator

No description provided.

@whatshappen
Copy link

synchronized保证了程序执行的可见性和原子性;
volatile只保证了程序的可见性,禁止指令的重排序;

@gabyallen
Copy link

1.volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
2.volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的
volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性
3.volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
4.volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化

@LvKang-insist
Copy link

synchronized 可以保证原子性。他可以保证 在同一时刻,只有一个线程可以访问被 synchronized 修饰的方法,或者代码块。
volatile 不能保证原子性。当时在使用这个关键字后。当被Volatitle 修饰字段的值发生改变后,其他线程会立刻知道这个值已经发生变化了。volatitle 可以保证可见性和有序性。

@yangfanggang
Copy link

打卡打卡

synchronized 可以保证原子性,可以用来进行线程同步,防止多线程出现的问题,可修饰 方法、类、代码块

volatile 不能保证原子性。我记得我在加解密网络请求的封装内见过,可以让其具有可见性,多线程操作时能发现olatitle 修饰字段的值变化

@Moosphan Moosphan added the Java label May 21, 2019
@MIkeeJY
Copy link

MIkeeJY commented Aug 5, 2019

1、volatile不会进行加锁操作
volatile变量是一种稍弱的同步机制在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比synchronized关键字更轻量级的同步机制。
2、volatile变量作用类似于同步变量读写操作
从内存可见性的角度看,写入volatile变量相当于退出同步代码块,而读取volatile变量相当于进入同步代码块。
3、volatile不如synchronized安全
在代码中如果过度依赖volatile变量来控制状态的可见性,通常会比使用锁的代码更脆弱,也更难以理解。仅当volatile变量能简化代码的实现以及对同步策略的验证时,才应该使用它。一般来说,用同步机制会更安全些。
4、volatile无法同时保证内存可见性和原子性
加锁机制(即同步机制)既可以确保可见性又可以确保原子性,而volatile变量只能确保可见性,原因是声明为volatile的简单变量如果当前值与该变量以前的值相关,那么volatile关键字不起作用,也就是说如下的表达式都不是原子操作:“count++”、“count = count+1”。
当且仅当满足以下所有条件时,才应该使用volatile变量:
1、 对变量的写入操作不依赖变量的当前值,或者你能确保只有单个线程更新变量的值。
2、该变量没有包含在具有其他变量的不变式中。
总结:在需要同步的时候,第一选择应该是synchronized关键字,这是最安全的方式,尝试其他任何方式都是有风险的。尤其在、jdK1.5之后,对synchronized同步机制做了很多优化,如:自适应的自旋锁、锁粗化、锁消除、轻量级锁等,使得它的性能明显有了很大的提升。

@kuye910
Copy link

kuye910 commented Jan 5, 2022

0、volatile的本质上是告诉JVM当前变量的值是不确定的,需要得到及时的更新,所以会把它放到工作内存当中,而synchronized会锁定该变量,只有当前线程可以访问,其他线程会被阻塞。volatile不会造成线程阻塞,synchronized则有可能会出现。

1、volatile在线程同步情况下,要比synchronized性能要好,但是volatile只能作用于变量上,而synchronized可以作用于方法或代码块

2、volatile可以保证变量的可见性,但不能保证原子性,而synchronized可以保证两者

3、volatile解决的是多个线程对变量的可见性,而synchronized解决的是多个线程之间访问资源的同步问题

@zxw1962
Copy link

zxw1962 commented Jan 26, 2023

volatile可以保证内存可见性、有序性(禁止指令重排);
synchronized可以保证内存可见性、原子性和互斥性(无禁止指令重排的作用哦);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants