线程安全的实现方法

本文介绍了线程安全的定义,即对象可被多个线程同时安全使用。还阐述了实现线程安全的方法,包括互斥同步(如synchronized和Reentrantlock)和非阻塞同步。同时对比了乐观锁和悲观锁,分析了它们的特点及适用场景,如悲观锁适用于多写,乐观锁适用于多读少写。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1什么是线程安全:

如果一个对象可以安全的被多个线程同时使用,那他就是线程安全的。

如何实现线程安全:

1.互斥同步。

互斥是方法,同步是目的,互斥同步的主要问题是线程阻塞和唤醒所带来的性能问题,属于一种悲观的并发策略。

实现同步主要有(1)加synchronized (2)重入锁Reentrantlock。

关于synchronized和Renntrantlock的区别

(1).两者都具备线程可重入的,只是代码写法上有区别,一个表现为API原生的互斥(lock和unlock方法配合try/finally语句块来完成),另一个表现为原生语法层面的互斥锁。

(2).Reentrantlock相比synchronized增加了新的高级特性(a.等待可中断b.可实现公平锁c.锁可以绑定多个条件)

 

2.非阻塞同步

基于冲突检测的乐观并发策略:先进行操作,如果没有其他线程争用共享数据,那操作就成功了,如果共享数据有争用,产生了冲突,就采取其他措施(常见的有不断重试,直到成功。),乐观并发策略需要"硬件指令集的发展"的支持。

 

关于乐观锁和悲观锁:

悲观锁:总是假设最差的情况,每次操作数据都认为别人会进行修改,所以每次拿数据的时候都会对数据进行加锁,这样别人想拿这个数据就会阻塞直到拿到锁,具体的应用有mysql的行锁,表锁,读锁(别人不能进行写),写锁,java的synchronized和Reentrantlock。适用场景是:多写的场景,因为如果多写的场景用乐观锁的话,比如CAS

java中synchronized和renntrantlock线程阻塞和唤醒涉及到操作系统用户态内核态的切换,浪费cpu资源,而CAS操作基于硬件的实现不需要进入到内核,不需要切换线程,但是如果多写的场景,线程竞争激烈,cas操作会一直等待,直到耗尽cpu分配给该线程时间片,从而降低效率。

乐观锁:总是假设最好的情况,拿数据的时候别人不会修改,但是在更新数据的时候会判断一下在这期间别人有没有更新这个数据,可以使用版本号 和CAS实现,适用的场景:多读少写的场景。

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值