zoukankan      html  css  js  c++  java
  • 每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列

    每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列,就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程,当一个被线程被唤醒 (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  那么阻塞队列 里 线程将一直处于阻塞状态,即使就绪队列里 线程都执行完了,阻塞队列 里 线程也将一直处于阻塞状态

    --------------某一线程释放锁之后,将会从就绪队列中 随机找出?(有疑问) 一线程,使之获得锁资源。 

  • 相关阅读:
    我太难了
    树状数组模板
    题解 洛谷P1196 【[NOI2002]银河英雄传说】
    poj 2352 & Ural 1028 数星星 题解
    棋盘覆盖 题解
    2015 JSOI冬令营训练 彩色格子 题解
    题解 UVA12716 GCD等于XOR GCD XOR
    第一篇博客
    2019.8.26 小结
    2019.8.24 小结 (关于树状数组,线段树小结)
  • 原文地址:https://www.cnblogs.com/01picker/p/4832506.html
Copyright © 2011-2022 走看看