杠精派
派聪明
0/512

热门评论

嘿嘿 2026年08月28日 22:17
引用原文:va中,关键字synchronized可以保证在同一个时刻,只有一个线程可以执行某个方法或者某个代码块(主要是对方法或者代码块中存在共享数据的操作),同时我们还应该注意到synchronized另外一个重要的作用,synchronized可保证一个线程的变化(主要是共享数据的变化)被其他线程所看到(保证可见性,完全可以替代Volatile功能)。
@派聪明 可见性不是只可以看到之前的数据吗只有在释放整个过程才可以进行新的数据吗
点赞
回复1 取消回复
派聪明 2026年08月28日 22:18
您的理解基本正确,我帮您梳理一下synchronized的可见性机制: ## synchronized的可见性含义**可见性是指:一个线程对共享变量的修改,其他线程能够看到最新的值**,而不是只能看到“之前的数据”。 具体规则是(基于JMM的happens-before规则): 1. **线程解锁前**,必须把共享变量的最新值刷新到主内存2. **线程加锁时**,必须从主内存重新读取共享变量的最新值## 为什么不是“只能看旧数据” 按监视器锁规则:**解锁操作 happens-before 后续对同一把锁的加锁操作**。 举例: ```javapublic synchronized void writer() { a++; } //线程A:a=1,解锁时刷回主内存public synchronized void reader() { int i = a; } //线程B:加锁时从主内存读,看到的是a=1``` 线程B在**获取锁成功之后**,看到的a就是线程A修改后的最新值1,不是旧值。 ## 您说的“释放整个过程才可以进行新的数据”怎么理解可以这么理解: - 在线程A**持有锁期间**,其他线程无法进入同步块,根本看不到中间的修改过程- 只有线程A**释放锁后**,其他线程获取锁时,才能看到A修改后的**最终结果** 所以可见性保证的是“锁释放后,其他持锁线程能看到最新结果”,而不是说只能看到旧数据。这正是它能替代volatile的原因——volatile保证每次读写都直接操作主内存,synchronized则通过“加锁-解锁”的内存屏障实现同样的效果。
点赞
回复 取消回复

4 条评论

嘿嘿 2026年08月28日 22:21
引用原文:va中,关键字synchronized可以保证在同一个时刻,只有一个线程可以执行某个方法或者某个代码块(主要是对方法或者代码块中存在共享数据的操作),同时我们还应该注意到synchronized另外一个重要的作用,synchronized可保证一个线程的变化(主要是共享数据的变化)被其他线程所看到(保证可见性,完全可以替代Volatile功能)。
@派聪明 那我要是在还没更新之前,在更新中就获取是之前的还是之后的这个又不是将这个京城给锁死了
点赞
回复1 取消回复
派聪明 2026年08月28日 22:22
# 关于你的疑问:synchronized下的数据可见性问题你问的是:如果一个线程还在更新数据的过程中,另一个线程就去读取,读到的是更新前还是更新后的值? ##核心答案**你根本读不到“更新中”的状态**——因为锁的存在,另一个线程根本进不来。 synchronized 的机制是这样的: 1. **互斥性(锁死)**:对,它确实是“锁住了”。当一个线程A持有锁在执行同步代码块时,线程B尝试获取同一把锁会被**阻塞等待**,根本无法进入同步区域读取数据。 2. **可见性(内存语义)**:线程A**释放锁**时,会把工作内存中的修改刷新到主内存;线程B**获取锁**时,会从主内存重新读取最新值。 所以时序是: ``` 线程A:获取锁 →修改数据 →释放锁(刷新到主内存) 线程B: (阻塞等待)→获取锁 → 读到的一定是A改完之后的值``` **你永远不会读到“改了一半”的中间状态**,要么读到之前的旧值(在A加锁前读),要么读到之后的最新值(在A释放锁后读)。 ## 注意一个前提这只在**读和写用的是同一把锁**时才成立。如果: - 写的方法用 synchronized,读的方法**不加锁**,那读线程可能读到旧值(没有可见性保证); -两个线程用**不同的锁对象**(比如一个锁实例、一个锁class对象),也不会互斥,可能出现数据不一致。 这也正是文中说“synchronized 可完全替代 volatile 功能”的原因:只要读写都在同一把锁的同步范围内,可见性和原子性就都有保障。
点赞
回复 取消回复
嘿嘿 2026年08月28日 22:17
引用原文:va中,关键字synchronized可以保证在同一个时刻,只有一个线程可以执行某个方法或者某个代码块(主要是对方法或者代码块中存在共享数据的操作),同时我们还应该注意到synchronized另外一个重要的作用,synchronized可保证一个线程的变化(主要是共享数据的变化)被其他线程所看到(保证可见性,完全可以替代Volatile功能)。
@派聪明 可见性不是只可以看到之前的数据吗只有在释放整个过程才可以进行新的数据吗
点赞
回复1 取消回复
派聪明 2026年08月28日 22:18
您的理解基本正确,我帮您梳理一下synchronized的可见性机制: ## synchronized的可见性含义**可见性是指:一个线程对共享变量的修改,其他线程能够看到最新的值**,而不是只能看到“之前的数据”。 具体规则是(基于JMM的happens-before规则): 1. **线程解锁前**,必须把共享变量的最新值刷新到主内存2. **线程加锁时**,必须从主内存重新读取共享变量的最新值## 为什么不是“只能看旧数据” 按监视器锁规则:**解锁操作 happens-before 后续对同一把锁的加锁操作**。 举例: ```javapublic synchronized void writer() { a++; } //线程A:a=1,解锁时刷回主内存public synchronized void reader() { int i = a; } //线程B:加锁时从主内存读,看到的是a=1``` 线程B在**获取锁成功之后**,看到的a就是线程A修改后的最新值1,不是旧值。 ## 您说的“释放整个过程才可以进行新的数据”怎么理解可以这么理解: - 在线程A**持有锁期间**,其他线程无法进入同步块,根本看不到中间的修改过程- 只有线程A**释放锁后**,其他线程获取锁时,才能看到A修改后的**最终结果** 所以可见性保证的是“锁释放后,其他持锁线程能看到最新结果”,而不是说只能看到旧数据。这正是它能替代volatile的原因——volatile保证每次读写都直接操作主内存,synchronized则通过“加锁-解锁”的内存屏障实现同样的效果。
点赞
回复 取消回复

目录