并发系列之synchronized与volatile的区别
1、使用上的区别
volatile只能修饰变量,synchronized修饰方法和语句块;
volatile例子:
volatile static boolean flag = true;
synchronized例子:
synchronized(this){
}
synchronized static String getName() {
}
2、对原子性的保证
synchronized能够保证原子性,volatile不能保证原子性;
volatile例子(运行结果是不对的):
public class WtyicySynchronized implements Runnable {
private volatile static int count = 0;
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
count++;
}
}
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
Thread thread = new Thread(new WtyicySynchronized());
thread.start();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("result: " + count);
}
}
synchronized例子:
public class WtyicySynchronized implements Runnable {
private static int count = 0;
@Override
public void run() {
synchronized (WtyicySynchronized.class) {
for (int i = 0; i < 10000; i++) {
count++;
}
}
}
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
Thread thread = new Thread(new WtyicySynchronized());
thread.start();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("result: " + count);
}
}
3、对可见性的保证
均可以保证可见性,但实现原理不一样,volatile对变量加了lock,synchronized使用monitorEnter和monitorExit;
volatile例子:ACC_VOLATILE,采用lock 汇编指令操作,lock add dword ptr [rsp],0h
private static volatile int count;
descriptor: I
flags: ACC_PRIVATE, ACC_STATIC, ACC_VOLATILE
synchronized例子:
4: monitorenter
5: iconst_0
6: istore_2
7: iload_2
8: sipush 10000
11: if_icmpge 28
14: getstatic #3 // Field count:I
17: iconst_1
18: iadd
19: putstatic #3 // Field count:I
22: iinc 2, 1
25: goto 7
28: aload_1
29: monitorexit
4、对有序性的保证和阻塞
均可以保证有序性,可是synchronized并发退化到串行;synchronized引发阻塞;volatile不会引发阻塞;
volatile例子:t1线程修改了数据,同步到祝内存中,马上就会通知其他线程,不存在线程阻塞。
synchronized例子:t1线程拿到锁时,t2线程就不能操作,就必须等待,多个线程排队的时候,就会存在线程阻塞。
5、往期佳文
5.1、面试系列
1、吊打面试官之一面自我介绍
2、吊打面试官之一面项目介绍
3、吊打面试官之一面系统架构设计
4、吊打面试官之一面你负责哪一块
5、吊打面试官之一面试官提问
6、吊打面试官之一面你有什么问题吗
······持续更新中······
5.2、技术系列
1、吊打面试官之分布式会话
2、吊打面试官之分布式锁
3、吊打面试官之乐观锁
4、吊打面试官之幂等性问题
5、吊打面试关之分布式事务
6、吊打面试官之项目线上问题排查
······持续更新中······
5.3、源码系列
1、源码分析之SpringBoot启动流程原理
2、源码分析之SpringBoot自动装配原理
3、源码分析之ArrayList容器
4、源码分析之LinkedList容器
5、码分析之HashMap容器
5.4、数据结构和算法系列
1、数据结构之八大数据结构
2、数据结构之动态查找树(二叉查找树,平衡二叉树,红黑树)
······持续更新中······
5.5、多线程系列
1、并发系列之初识多线程
2、并发系列之JMM内存模型
3、并发系列之synchronized解析
4、并发系列之volatile解析
······持续更新中······
本文深入探讨了Java中synchronized和volatile的使用区别,包括它们对原子性、可见性和有序性的保障。volatile仅能保证变量可见性,无法确保原子性,而synchronized则提供更全面的锁机制,确保线程安全。此外,volatile不会导致线程阻塞,而synchronized可能导致。了解这些差异对于优化多线程代码至关重要。

4114

被折叠的 条评论
为什么被折叠?



