应用场景: 生产者producer, 消费者consumer模式多线程情况
两个人a和b,a等着用钱.b存钱, a取钱
操作的一个账户的钱. 一个向卡里存钱,一个从卡里取钱 .
前提:
存之前, 账户金额为0.
未存钱, 不能取,
每次只能存2000元, 不取完, 不能存.
将需求转化成java逻辑
b存钱 -> 判断账户是否有钱 -> 没钱就存 -> 存完后,notify()唤醒a线程取钱,然后自己wait()
-> 有钱不存
a取钱 -> 判断账户是否有钱 -> 有钱取出 -> 取出后, 通知b存钱 就是notify()唤醒b, 然后自己wait()
-> 没钱不取
特点: 多个线程, 干着不同的活,操作相同的数据
a: 取钱线程 outputThread
b: 存钱线程 inputThread
账户: AccountPOJO 属性: 金额amount, flag标记 true有钱, false没钱
账户为一个对象, 编号, 金额, 标志位.
其中, 标志位用来存放是否有钱的标识: true有钱, false没钱
而a,b两个线程公用一个锁, 是账户对象. 锁对象通过创建两个实现Runnable接口的类的构造函数传递.
实现Runnable接口的类, 我称为线程实现类. 而具体业务实现, 就是他的run方法中代码
问题:
a取完钱, 告诉b, 哎. 我取完了.
也就是在a线程中获取到b线程,在唤醒b线程.
问: 怎么在a线程获取到b线程?并唤醒? 同样, b线程中如何获取到a线程, 对他唤醒呢???
想知道这个问题的答案, 需要查看Java的API, 查看wait与notify的方法在哪里定义.
是的, wait与 notify定义在Object对象中的, 并不是线程的方法.
wait与notify,notifyAll都是用在多线程,同步代码中的
而同步就需要用到 对象锁, 我们a和b共同操作一个账户, 这个账户对象, 就是对象锁.
为什么操作线程的方法要定义在Object类中呢?
锁可以是任意对象, 被任意对象调用的方法,定义在Object中
这些方法操作同步中的线程时, 都必须要标识他们所操作线程所持有的锁
只有多个线程使用同一个锁对象时, 锁对象才能把使用同一个锁,并且处于等待的线程唤醒
只有同一个锁上的被等待线程, 可以被同一个锁上notify唤醒.
以上这两句 " 只有", 意思是一样的, 看哪个更容易理解吧. 都是帮助理解的解释
当前同步方法中的锁对象,不能唤醒未使用该锁的线程,也就是说
不可以对不同锁中的线程进行唤醒,
等待和唤醒必须是同一个锁
添