JVM--线程安全

什么是线程安全?
当多个线程访问一个对象时,如果不用考虑这些线程在运行环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象是线程安全的。
各种操作共享数据分类:
不可变
绝对线程安全
相对线程安全
线程兼容
线程对立
线程安全的实现方法:
1.互斥同步:
临界区、互斥量和信号量都是主要的互斥实现方式
ReentrantLock高级功能:等待可中断、可实现公平锁、锁可以绑定多个条件


等待可中断是指当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情,可中断特性对处理执行时间非常长的同步块很有帮助
公平锁是指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁;而非公平锁则不保证这一点,在锁被释放时,任何一个等待锁的线程都有机会获得锁。synchronized中的锁是非公平的,ReentrantLock默认情况下是非公平的,但可以通过带布尔值的构造函数要求使用公平锁。
锁绑定多个条件是指一个ReentrantLock对象可以同时绑定多个Condition对象,而在synchronized中,锁对象的wait()和notify()或notifyAll()方法可以实现一个隐含条件,如果要和多于一个条件关联的时候,就不得不额外地添加一个锁,而ReentrantLock则无须这样做,只需多次调用newCondition()方法即可。
主要问题:进行线程阻塞和唤醒所带来的性能问题,因此这种同步也称为阻塞同步。
2.非阻塞同步:
测试并设置(Test-and-Set)
获取并增加(Fetch-and-Increment)
交换(Swap)
比较并交换(Compare-and-Swap,CAS)
加载链接/条件存储(Load-Link/Store-Conditional,下文称LL/SC)
CAS指令需要3个操作数,分别是内存位置(在Java中可以简单理解为变量的内存地址,用V表示)、旧的预期值(用A表示)和新值(用B表示)。CAS指令执行时,当且仅当V符合旧预期值A时,处理器用新值B更新V的值,否则它就不执行更新,但是无论是否更新了V的值,都会返回V的旧值,上述处理过程是一个原子操作。
CAS会产生ABA问题:如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然为A值,那我们就能说它的值没有被其他线程改变过了吗?如果在这段期间它的值曾经被改成了B,后来又被改回为A,那么CAS操作就会误认为它从来没被改变过。
3.无同步方案
可重入代码:可以在代码执行的任何时候中断,转而去执行另外一段代码(包括递归调用它本身),而在控制权返回后,原来的程序不会出现任何错误。
线程本地存储:如果一段代码中所需要的数据必须与其他代码共享,那就看看这些共享数据的代码是否能保证在同一线程中执行?如果能保证,我们就可以把共享数据的可见范围限制在同一线程之内,这样,无需同步也能保证线程之间不出现数据争用的问题。
锁优化:
锁优化技术:适应性自旋、锁消除、锁粗化、轻量级锁、偏向锁
自旋锁默认是关闭的,可以通过-XX:+UseSpinning参数开启
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值