线程安全的实现方法

2020-05-28  本文已影响0人  ACtong
一、互斥同步

互斥同步(Mutual Exclusion & Synchronization):是一种常见的也是最主要的并发正确性保证手段。

synchronized关键字经过javac编译后,会有两个字节码指令monitorentermonitorexit。这两个字节码指令都需要有一个reference类型的参数来指明要锁定和解锁的对象。如果synchronized明确指定了对象参数,就用对象参数,没有就修饰方法类型(如实例方法或类方法)

在执行moniterenter指令:首先尝试去获取对象的锁。如果这个对象没有被锁定,或者当前线程已经持有那个对象锁,就把锁的计算器加一,执行到moniterexit时,计数器就减一。一旦计算器为零,锁随之就被释放。如果获取对象失败,当前线程应该被阻塞等待,直到线程被释放为止。

结论:

  1. 被synchronized修饰的同步款对同一条线程来说时可重入的。意味着同一线程反复进入同步块也不会出现把自己锁死的情况。
  2. 被synchronized修饰的同步块在持有锁的线程执行完毕并释放之前,会无条件的阻塞后面其他的线程。
二、非阻塞同步

非阻塞同步锁:它是基于冲突检测的乐观并发策略,就是不管风险,先进行操作,那再进行其他的补偿措施,最常用的补偿措施是不断地重试,直到出现没有竞争的共享数据为止。

上面所说的互斥同步带来的主要问题是进行线程阻塞和唤醒所带来的性能开销,它也称为阻塞同步(Blocking Synchronization)。它是一种悲观的并发策略,其总认为只要不去做正常的同步措施(例如加锁),那就肯定会出现问题,但是这会影响性能开销。

三、无同步方案

如果让一个方法本来就不涉及共享数据,那它自然就不需要任何同步措施去保证正确性,因此有一些代码天生是线程安全的。

上一篇 下一篇

猜你喜欢

热点阅读