Java多线程中的 Lock, synchronized 和 volatile

0. 写在前面

Java 多线程编程中 Lock 的概念和synchronizedvolatile关键字是经常遇到的内容或者说知识点,本文是我最近学习多线程的个人总结,会说明这三者涉及的一些基础概念,所以它们不是很全面,跳动性会有点大,参考资料会在文章结尾给出。

前提条件

  • 最基本的,我觉得你需要了解线程的概念,这是最低要求了🤣。

1. 线程安全

线程安全是我们最常听到的名词,我直接拿出《Concurrency in Java》中对其的定义:

A class is thread‐safe if it behaves correctly when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment, and with no additional synchronization or other coordination on the part of the calling code.
当多个线程访问某个类时,不管运行时环境采用何种调用方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类时线程安全的。

你会发现,线程安全被限制在类级别(class level),我们也常听到某某某类不是线程安全的。举个例子,假使现在我们有一个ArrayList对象,当多个线程同时访问/操作该对象时,很有可能出问题,比如都调用其add方法,list 对象中的元素很有可能出现不一致的情况,当然还有许许多多其它的场景展示非线程安全。如果某类是线程安全的,那么你就可以放心地去使用它,而无需花费额外的精力保证线程安全。

补充:文章中多次提到的访问(access),比如访问某对象,这其中包含调用该对象的方法,在此,你可以理解为读写行为都会有。

当我们使用非线程安全的类时,为了保证正确的结果,就需要增加一些额外的操作,比如加锁,上面提到的协同(coordination),我现在还未涉及到,暂不做讨论。看起来,加锁似乎是万能的,因为当许多事情并行/异步运行时,加锁使得我们访问某个对象可以是串行/同步的。但是,从哲学方面考虑,事物总是有两面性,当在某些方面突出时,它肯定牺牲了其它的资源。加锁虽然可以解决我们遇到的绝大部分非线程安全的问题,但也带来了更大的开销,效率更低,所以我们需要一些更轻量的方式来满足不同的场景。

来到正题,synchronized使lock()/unlock()更为方便,volatile仅仅保证可见性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值