Java并发
Java并发
Mercy_丶 发表于10个月前
Java并发
  • 发表于 10个月前
  • 阅读 20
  • 收藏 0
  • 点赞 0
  • 评论 3

腾讯云 技术升级10大核心产品年终让利>>>   

并发的基础理念

并发的由来

在Java世界,类变量(static变量)和实例变量(类普通成员变量)是线程间共享的,当多个线程同时访问这些变量时,为了保证变量的数据的一致性必须对变量的访问加以控制--锁,但是锁(synchronize)会导致整个系统的性能低下,于是人们开始通过各种手段来实现高效并发。

互斥同步

synchronize

synchronize是java中最常见最粗暴的的并发手段,synchronize在资源竞争不是很激烈的情况下是很不错,但是一旦处于高并发的情况下性能就大大降低了,Java中HashTable与synchronize密切相关,几乎所有方法都加上synchronize。

ReentrantLock

其实ReentranLock和synchronize原理一样,也是通过java加锁来实现同步。
他同lock()和unLock()来实现加锁和锁释放。此外ReentranLock还增加一下三项高级功能: 等待可中断 ,可实现公平锁 ,锁可以绑定多个条件.

从性能来说,在JDK1.5之前ReentrantLock要优于synchronize,但是1.6JDK及以上对synchronize做了很多针对锁的优化措施,性能上两者几乎持平。所以单从性能上,JDK1.6以后的版本推荐使用synchronized。

非阻塞式同步

互斥同步最主要的问题就是进行线程阻塞和唤醒所带来的性能问题,因此这种同步也称为阻塞同步。从处理问题的方式来说,互斥同步是一种悲观并发策略,因为他总是以为不加同步措施就会出现问题。
于是人们就有了另外一种选择:基于冲突检测的乐观并发策略,乐观并发策略很多实现都是不需要吧线程挂起,因此这种同步操作称为非阻塞同步。

CAS指令

CAS(compare and swap)即比较交换,随着硬件的发展,这条看上去是需要多次操作才能完成的行为只需要处理器一条指令就能完成。
CAS指令需要3个操作数,分别是内存位置(在Java中可以简单理解为变量的内存地址,用V表示)、旧的预期值(用A表示)和新值(用B表示)。CAS指令执行时,当且仅当V=A时,就用新值B来更新V的值,否则就不执行更新。(当无论V是否更新了值都放回V的就值),上述就是一个原子操作。
在Java中,sun.misc.Unsafe类里面就提供了compareAndSwapInt()compareAndSwapLong() 等操作方法。在原子类中AtomicInteger就有体现。在JDK8中ConcurrentHashMap就是使用这样的方法实现的(JDK8之前是用分段锁方式实现)。

关于volatile型变量

说到并发人们常常会提到volatile。volatile变量是Java提供的轻量级的同步机制,但是在真正的开发中并没有得到重视。

并发中的三个特性

在介绍volatile之前先介绍一下并发中的三个特性:

  • 原子性
  • 可见性
  • 有序性

volatile变量第一个特性就是: 保证变量在所有线程的可见性。(即线程更新完立即同步回主内存)
volatile变量第二个特性就是:禁止指令重排序优化,保证有序性。
所以说volatile变量不能保证变量操作的的原子性,所以应用volatile变量在并发场景中一定要慎重。
符合下列场景可以使用volatile变量,负责依然需要加锁来保证操作的原子性:

  • 运算结果不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。
  • 变量不需要与其他的状态变量共同参与不变约束。
共有 人打赏支持
粉丝 8
博文 36
码字总数 15339
评论 (3)
我是偶哦
不知道为什么,感觉布局好丑
Mercy_丶

引用来自“我是偶哦”的评论

不知道为什么,感觉布局好丑
是挺丑的
我是偶哦

引用来自“我是偶哦”的评论

不知道为什么,感觉布局好丑

引用来自“Mercy_丶”的评论

是挺丑的
:flushed:
×
Mercy_丶
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: