<commit_before>---
layout: post
title: 浅谈java volatile
---


最近有点空闲时间，看了一下《Netty权威指南》，看到了关于volatile的一段论述：

	一些人认为使用volatile可以代替传统锁，提升并发性能，这个认识
	是错误的。volatile仅仅解决了可见性的问题，但是它并不能保证互
	斥性，也就是说多个线程并发修改某个变量时，依旧会产生多线程的问
	题。因此，不能靠volatile来完全替代传统的锁。
	
	根据经验总结，volatile最适合使用的是一个线程写、其他线程读的
	场合，如果有多个线程并发写操作，仍然需要使用锁或者线程安全的容
	器或者原子变量来代替。

自己之前纠结过一段时间，这里说一下自己的理解，volatile变量作用有两方面：可见性和防止重排序。这个就不多说了，这里主要说一下volatile变量在什么情况下可以抛弃锁。

首先应该确定一个前提，就是volatile变量不能牵扯到与其它变量的不变约束中，也就是说，volatile变量的变化不会与其它变量的变化有任何联系，如果volatile变量牵扯到不变约束中，单纯的volatile肯定无法维护多个变量的并发变化。

确定了这样一个前提，我认为volatile变量在两种情况下可以完全抛弃锁：

1. 单线程写，多线程读

	在这种情况下，volatile变量的修改只来自一个线程，而且volatile可以保证对于该变量的修改可以及时反映给读取该变量的线程

2. 多线程并发写

	对于多个线程并发修改volatile变量的情况，如果赋值操作可以保证是原子的，例如java基本类型（排除long和double）的简单赋值操作，一样可以抛弃锁。这里最重要的还是对于volatile变量的修改操作是原子性的，这个原子性是由变量自身保证的，对于int型变量来说int a＝10可以保证赋值操作的原子性，但是int a=++b这样的赋值操作就不能保证了。总结一下就是如果变量的修改不依赖变量的当前值并且这个变量的修改是原子的，那么在多线程并发修改该变量的情况下，简单的volatile就可以保证变量可以被正确的使用。<commit_msg>format<commit_after>---
layout: post
title: 浅谈java volatile
---

最近有点空闲时间，看了一下《Netty权威指南》，看到了关于volatile的一段论述：
>一些人认为使用volatile可以代替传统锁，提升并发性能，这个认识是错误的。volatile仅仅解决了可见性的问题，但是它并不能保证互斥性，也就是说多个线程并发修改某个变量时，依旧会产生多线程的问题。因此，不能靠volatile来完全替代传统的锁。
>
>根据经验总结，volatile最适合使用的是一个线程写、其他线程读的场合，如果有多个线程并发写操作，仍然需要使用锁或者线程安全的容器或者原子变量来代替。

自己之前纠结过一段时间，这里说一下自己的理解，volatile变量作用有两方面：可见性和防止重排序。这个就不多说了，这里主要说一下volatile变量在什么情况下可以抛弃锁。

首先应该确定一个前提，就是volatile变量不能牵扯到与其它变量的不变约束中，也就是说，volatile变量的变化不会与其它变量的变化有任何联系，如果volatile变量牵扯到不变约束中，单纯的volatile肯定无法维护多个变量的并发变化。

确定了这样一个前提，我认为volatile变量在两种情况下可以完全抛弃锁：

1. 单线程写，多线程读
	
	在这种情况下，volatile变量的修改只来自一个线程，而且volatile可以保证对于该变量的修改可以及时反映给读取该变量的线程

2. 多线程并发写

	对于多个线程并发修改volatile变量的情况，如果赋值操作可以保证是原子的，例如java基本类型（排除long和double）的简单赋值操作，一样可以抛弃锁。这里最重要的还是对于volatile变量的修改操作是原子性的，这个原子性是由变量自身保证的，对于int型变量来说int a＝10可以保证赋值操作的原子性，但是int a=++b这样的赋值操作就不能保证了。总结一下就是如果变量的修改不依赖变量的当前值并且这个变量的修改是原子的，那么在多线程并发修改该变量的情况下，简单的volatile就可以保证变量可以被正确的使用。
{'fraction_non_alphanumeric': 0.0720384204909285, 'fraction_numerical': 0.004268943436499467, 'mean_word_length': 18.736842105263158, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2102046', 'n_tokens_mistral': 1578, 'n_tokens_neox': 1752, 'n_words': 44}