素材牛VIP会员
java对于对象锁是如何管理的?
 16***50  分类:Java代码  人气:807  回帖:1  发布于6年前 收藏

我在看一本多线程的书时, 上面说java对于每个对象锁都有两个队列, 一个就绪队列, 一个等待队列. 我联想到操作系统对于进程资源的管理, 操作系统只有一个就绪队列, 对于不同的资源有不同的等待队列. 因此我对书上的这句话很怀疑, java对于对象锁是怎么管理的呢?

 标签:java

讨论这个帖子(1)垃圾回帖将一律封号处理……

Lv6 码匠
lk***29 CEO 6年前#1

每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列,就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程,当一个被线程被唤醒 (notify)后,才会进入到就绪队列,等待获得锁。你说的等待队列也就是阻塞队列。

例如:当一开始线程a第一次执行对象account.add()方法时,JVM会检查锁对象account的就绪队列是否已经有线程在等待,如果有则表明account的锁已经被占用了,由于是第一次运行,account的就绪队列为空,所以线程a获得了锁, 执行account.add方法。如果恰好在这个时候,线程b要执行account.withdraw方法,因为线程a已经获得了锁还没有释放,所以线程b要进入account的就绪队列,等到得到锁后才可以执行。一个线程执行临界区代码过程如下:

1.获得同步锁
2.清空工作内存
3.从主存拷贝变量副本到工作内存
4.对这些变量计算
5.将变量从工作内存写回到主存
6.释放锁

可见,synchronized既保证了多线程的并发有序性,又保证了多线程的内存可见性。notify 不会释放锁,而是通知锁对象的阻塞队列里的某一线程(被阻塞,即主动调用wait方法),进入就绪队列。线程释放锁的方式,通常是 主动调用wait方法、同步代码块结束释放锁资源。notifyall 是 唤醒阻塞队列里的所有阻塞线程,他们都将进入就绪队列,而notify的数量是一个。同步代码块结束释放锁资源,对象就绪队列中的某一线程获得锁资源而开始线程;如果不使用notify 那么阻塞队列 里 线程将一直处于阻塞状态,即使就绪队列里 线程都执行完了,阻塞队列 里 线程也将一直处于阻塞状态.某一线程释放锁之后,将会从就绪队列中 随机找出?(有疑问) 一线程,使之获得锁资源。

 文明上网,理性发言!   😉 阿里云幸运券,戳我领取