JVM-线程安全以及锁优化

1,线程安全的定义

定义:当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象是线程安全的。

如果将线程安全的“安全程度”由强至弱来排序,那么可以分为以下5类:不可变、绝对线程安全、相对线程安全、线程兼容以及线程对立。

1.1,不可变

不可变的对象一定是线程安全的,无论是对象的方法实现还是方法的调用者,都不需要再采取任何线程安全保障措施。

1.2,绝对线程安全

不管运行环境如何,调用者都不需要任何额外的的同步措施

1.3,相对线程安全

相对线程安全就是我们平时说的线程安全,它需要保证对这个对象单独的操作是线程安全的,我们在调用时不需要做额外的保障措施,但对于一些特定顺序的连续调用,就可能需要在调用端使用额外的同步手段保障调用的正确性。

java中,大部分线程安全属于这种类型,如Vector、HashTable等。

1.4,线程兼容

线程兼容是指对象本身不是线程安全的,但是可以通过调用端正确使用同步手段来保证对象在并发环境中可以安全的使用。

1.5,线程对立

线程对立是指无论调用端是否采用了同步措施,都无法在多线程环境中并发的使用代码,线程不安全的。

2,线程安全的实现方法

2.1,互斥同步

Synchronized关键字和ReentrantLock就是基于互斥同步实现的。

Synchronized关键字:阻塞或者唤醒一个线程,都需要内核支持,需要从用户态转换到内核态,状态转换消耗的时候有可能比代码执行的时候还要长,是一个重量级锁。Synchronized关键字具有可重入性,Synchronized是非公平锁。

ReentrantLock:具有可重入性,增加了一些高级功能,主要有三项:等待可中断、可实现公平锁以及锁可以绑定多个条件。

2.2,非阻塞同步

非阻塞同步,也就是基于冲突检测的乐观并非策略,通俗说,就是先进行操作,如果没有其他线程争用共享资源,那操作成功了;如果共享数据有争用,产生了冲突,那就采用其他补救措施(通常是不断循环重试直到成功)。

2.4,无同步方案

有一些代码天生就是线程安全,所以无需同步去保证其线程安全性。如:

可重入代码:这种代码也叫纯代码,可以在代码执行的任何时刻中断它,转而去执行另外的代码,而在控制权返回后,原来的代码不会出现任何错误。

线程本地存储:如果数据必须共享,那么就看看这些共享数据能否放在同一个线程中。

3,锁优化

3.1,自旋锁与自适应自旋锁

线程的状态切换,需要从用户态转到内核态,性能比较低。因此当两个线程以上并发,请求锁的线程没请求到锁的时候,我们会让请求锁的线程“稍等一会”,不放弃处理器执行时间,看持有锁的线程是否会释放锁。让请求锁的线程执行一个忙循环,这就是自旋。自旋的次数可以通过jvm的参数来设定。

适应性自旋锁:自旋的时间不再固定,更加智能。在同一个锁对象上,自旋等待刚刚获取过锁,并且持有锁的线程正在运行中,那么jvm会认为这次自旋会有很大几率成功,因此会增加等待线程的自旋时间。如果对于某个锁,自旋很少成功,那么以后获取这个锁有可能忽略自旋过程。

3.2,锁消除

指虚拟机即时编译器在运行时,对一些代码上要求同步,但是检测到不可能存在共享数据竞争的锁进行消除。

3.3,锁粗化

对一个对象的操作反复加锁和解锁,会导致不必要的性能损耗。 如:对StringBuffer对象反复调用append()方法,会将锁扩展到第一个append()操作之前直至最后一个append()操作之后。

3.4,轻量级锁

需要先了解对象头的结构。

虚拟机会使用CAS操作尝试将对象的Mark Word更新为指向Lock Record的指针,如果更新成功了,则获取锁成功了。如果更新失败了,虚拟机首先去检测对象头的Mark Word是否指向当前线程的栈帧,如果是则当前线程已经拥有了这个对象的锁,否则证明这个锁对象已经被其他线程占用。

目的:在没有多线程竞争的前提下,减少传统重量级锁的使用操作系统互斥量产生的性能消耗。如果存在锁竞争,除了互斥量的开销外,还有CAS的操作,此时,轻量级锁比重量级锁更慢。

3.5,偏向锁

偏向锁就是在无竞争的情况下把整个同步消除掉,连CAS操作都不做了。这个锁会偏向第一个获得它的线程,如果接下来的执行过程中,该锁没有被其他线程获取,则持有偏向锁的线程永远不需要再同步。

这个锁好像没什么用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值