java线程安全和锁优化

一、线程安全

不可变

不可变对象一定是线程安全的。当一个不可变对象呗构建出来,没有发生this引用逃逸,在外部的状态永远不会改变。在多线程情况下,也就不会出现不一致的情况。不可变对象,是最简单最纯粹的线程安全。

被final修饰的基本数据类型,就是不可变的。

不可变对象,对象的行为不会对其产生任何影响。典型的就是String类型,无论如何调用substring,replace等方法,都会返回一个新的对象,而不会影响原来的值。String就是一个不可变类。

最简单的实现不可变类的方式,就是将对象的带有状态的变量都声明为final。这样对象本身在调用完构造方法之后,得到的就是一个不可变对象。

String类,枚举类,java.lang.Number下部分子类,如,Long,Double等包装类型,BigInteger,BigDecimal等大数据类型。都是不可变类。原子类并非不可变类。

线程安全的实现方法

1.互斥同步即synchronized关键字实现。

synchronized关键字在编译之后,会在同步块前后行成monitorenter和monitorexit两个字节码指令,这两个指令都需要一个对象的引用来指明锁定和解锁的对象。在执行minitorenter指令时,会尝试获取对象的锁,把锁计数器加1,在执行monitorexit时,会将对象的锁计数器减1,当计数器为0时,代表锁被释放。同步代码块锁是可以重入的,来防止自身对象被锁死的情况。

除了synchronized之外,还有重入锁,即java.util.concurrent包下的ReentrabtLock来实现同步,与synchronized的区别在于:

(1)等待可中断,即线程在阻塞的情况下,等待获得对象锁的时候,时间过长可以中断,去执行别的事情。

(2)公平锁,即线程在阻塞的情况下,可以按时间先后顺序执行。synchronized的锁是非公平的。

(3)锁绑定多个条件。ReentrantLock对象可以同时绑定多个Condition对象。而synchronized中,锁对象的wait()notify(),notifyall()可以实现一个隐含的条件。

2.非阻塞同步

互斥同步是一直阻塞的同步方式,带来的性能问题就是,加锁和解锁操作带来了不必要的开销。

3.无同步方案

锁优化

1.自旋锁和自适应自旋

2.锁消除

3.锁粗化

4.轻量级锁

5.偏向锁

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值