java同步锁的实现原理简单总结

ps:纯属个人简单总结,有不当之处或不合事实请指出,谢谢!


java中同步锁使用synchronized实现,不管是作用在方法上还是代码快上,作用在方法上分静态方法和实例方法,作用在代码快上需要在后面添加锁的对象,实现原理是在作用对象的锁上添加拥有者,java每个对象头上可能包含monitor监视器锁,而锁上面标记了锁的拥有者,即一个线程,当线程进入同步块中时,检查锁对象中的owner是否已经有其他线程,如果是那么线程进入阻塞状态,进入等待队列,如果不是则修改对象锁的拥有者为当前线程,当线程退出同步块是,修改对象锁的拥有者为空,其他等待线程进入竞争锁,获得锁的线程优先执行代码块,假定线程在代码块还没有执行完成,那么对象锁能不能释放呢,答案是可以的,通过调用被锁对象的wait方法,将当前对象锁的拥有者修改为空,那么当前执行的线程会释放锁,进入等待阶段,其他阻塞状态的线程就会开始竞争锁,那么执行同步块中途释放锁进入等待的线程怎么继续执行呢,需要其他线程调用被锁对象的notify方法或notifyAll方法,通知处在等待状态的线程,wait/notify一般用于线程间协作使用,且wait/notify方法必须写在同步块中,因为这两个方法都是释放锁,所以前提是需要活得锁,sleep和wait的区别,sleep是Thread方法,是使当前线程进入休眠状态,和锁没关系,wait是使当前对象上的锁拥有者修改为空,使得当前线程释放锁。

调用了wait方法进入等待的线程,必须被其他线程对用notify或notifyAll才会被唤醒,否则一直处于等待状态中

什么是monitor?
monitor是和java对象一一对应的,每个java对象都有一个monitor对象,monitor对象中记录了线程所有者,即当前java对象监视器属于哪个线程拥有,monitor还包括了entryList即,需要进入同步块,但没有获得锁的线程列表,还包括waitSet,即拥有对象锁后在执行代码中途调用wait方法后的线程列表,当在同步代码块中调用notify或notifyAll,只会唤醒waitSet中的线程,并将锁给其中的一个线程。

notify只会随机唤醒一个等待的线程,而notifyAll会唤醒所有在等待的线程。
被唤醒的线程和在代码块中未获取到锁的线程一样都需要参与竞争锁。

java线程状态:
NEW RUNNABLE WAITING TIMED_WAITING BLOCKED TERMINATED

NEW:线程创建状态,即一个线程实例被创建后的状态。
RUNNABLE:调用线程的start方法后,进入就绪状态,处于运行中的线程也是该状态
WAITING: 等待中的状态,表示在一个对象监视器上等待的状态,调用对象的wait方法,当前线程会进入等待状态,等待该对象监视器被唤醒.
TIMED_WAITING:等待中状态,线程调用sleep方法会进入到改状态。
BLOCKED:阻塞状态,如进入同步块前未获取到锁时,进入阻塞状态。
TERMINATED:终止状态,如线程执行完毕。

wait notify notifyAll方法:
相同点:必须获取到当前对象监视器的锁。
不同点:wait方法调用后会释放当前对象的锁,当前对象进入WAITING状态。
notify或notifyAll调用后会唤醒处于该对象锁上WAITING的线程,但并不会释放锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值