Java积累:volatile 和 synchronized

volatile

Volatile用来对共享变量的访问进行同步。上一次写入操作的结果对下一次读取操作是肯定可见的。

​ 在写入volatile变量值后,CPU缓存中的内容会被写回主存中;在读取volatile变量时,CPU缓存中的对应内容会被置为失效状态,重新从主存中读取。

​ 将变量声明为volatile相当于单个变量的读取和写入添加了同步操作。但是volatile在使用时不需要利用锁机制,因此性能要优于synchronized关键词。

​ Volatile的主要作用是确保对一个变量的修改被正确地传播到其他线程中。

​ 常使用volatile变量的一个场景是把作为循环结束的判断条件的变量声明为volatile。

synchronized

Synchronized是基本的线程同步方式之一。Synchronized可以添加到方法或代码块上。主要用来实现线程之间的互斥,即同一时刻只有一个线程允许执行特定的代码,来保证多个线程访问共享变量时的正确性。

​ 声明synchronized的方法或代码块在同一时刻只能有一个线程允许访问的。如果当前已经有线程正在访问synchronized方法或代码块,那么其他试图访问该方法或代码块的线程会处于等待状态。这种互斥性使该方法或代码块中的代码逻辑实际上成为了一个原子操作。

​ 所有的java对象都有一个与之关联的监视器对象(monitor),允许线程在该监视器对象上进行加锁和解锁操作。每个synchronized关键词在使用时都与一个监视器对象相对应。对于声明为synchronized的方法,静态方法对应的监视器对象是所在java类对应的Class类的对象所关联的监视器对象,而实例方法使用的是当前对象实例所关联的监视器对象。对于synchronized代码块,对应的监视器对象是synchronized代码块声明中的对象所关联的监视器对象。

​ 在一个线程允许执行方法或代码块之前,需先获取对应的监视器对象上的锁。在执行完后,该线程所持有的锁会被自动释放。上一次的解锁操作肯定在下一次的成功加锁操作前发生,由于解锁操作是上一次线程在synchronized方法或代码块中执行的最后一个动作,而加锁是在下一次线程执行synchronized方法或代码块的第一个动作,所以上一次线程运行时对共享变量的修改对下一次线程中的动作是肯定可见的。

​ 当锁被释放时,对共享变量的修改会从CPU缓存中直接写回到主存中;当锁被获取时,CPU缓存中的内容会被置为无效状态,从主存中重新读取共享变量的值。当有线程在执行synchronized方法或代码块时,其他线程由于无法获取锁而处于等待状态,不会影响当前线程的运行。

public class Jdk7Synchronized {

	private int num = 0;
	private static int value = 0 ;
	
	// 对象的实例方法 同步时使用的监控器对象是当前对象的实例所关联的监控器对象
	public synchronized int addNum(){
		return num++ ;
	}
	
	public int getAddNum(){
		// 代码块 同样使用的是当前对象的实例this所关联的监控器对象
		synchronized (this) {
			return num++;
		}
	}
	
	// 静态方法 监控器对象是 Jdk7Synchronized.class所关联的监控器对象
	public synchronized static int getValuePlus(){
		return value++;
	}
}


synchronized和volatile比较



关键字synchronizedvolatile进行比较:

​ A、 关键字volatile是线程同步的轻量级实现,所以性能会比synchronized要好。

​ B、 Volatile只能修饰变量,而synchronized可以修饰方法及代码块。

​ C、 多线程访问volatile不会发生阻塞,而synchronized会发生阻塞。

​ D、 Volatile能保证数据的可见性,但不能保证原子性;

​ 而synchronized可以保证原子性,也可以间接保证可见性,因为它会将私有内存和公有内存中的数据做同步。

​ E、 Volatile解决的是变量在多线程间的可见性;而synchronized解决的是多个线程间访问资源的同步性。

刚开始写微信公众号,请多多关注,欢迎,多谢!

微信公众号:《Java学习积累》
请关注一下,多谢!!!
微信公众号:Java学习积累

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java中,synchronizedvolatile是用来实现多线程同步的关键字。它们在实现多线程同步的机制上有一些不同之处。 首先,synchronized关键字提供了互斥访问的能力,即同一时刻只允许一个线程访问被synchronized修饰的代码块或方法。它可以解决并发编程中的原子性、可见性和有序性问题。通过获取锁来实现同步,保证了代码的原子性和有序性。同时,synchronized也保证了共享变量在不同线程之间的可见性。 而volatile关键字主要用来解决共享变量的可见性和有序性问题。使用volatile修饰的变量会强制线程从主内存中读取变量的最新值,而不是使用缓存中的旧值。这样可以确保一个线程对volatile变量的修改对其他线程是可见的。然而,volatile不能保证原子性,因此在执行复合操作时仍然需要加锁来保证原子性。 此外,synchronized关键字可以用于修饰代码块或方法,而volatile只能修饰变量。另外,synchronized是悲观锁,会导致线程阻塞等待锁的释放,而volatile是乐观锁,不会阻塞线程,而是要求线程自己通过CAS操作来保证数据一致性。 综上所述,synchronizedvolatile关键字在实现多线程同步的机制上有一些不同。synchronized提供了更全面的多线程同步能力,可以解决原子性、可见性和有序性问题,但会引入线程阻塞。而volatile关键字主要解决共享变量的可见性和有序性问题,但无法保证原子性。因此,在选择使用synchronized还是volatile时,需要根据具体的应用场景和需求进行权衡。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [synchronizedvolatile 的区别是什么?](https://blog.csdn.net/m0_68464502/article/details/131107637)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [4个点说清楚Javasynchronizedvolatile的区别](https://blog.csdn.net/wanghao112956/article/details/100133457)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Java关键字volatilesynchronized作用和区别](https://download.csdn.net/download/weixin_38557838/12778536)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天涯共明月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值