Java总结篇系列:Java多线程(三)

awAmount
125      */
126     public synchronized void draw(double drawAmount, int i) {
127         if (!flag) {
128             // 账户中还没人存钱进去,此时当前线程需要等待阻塞
129             try {
130                 System.out.println(Thread.currentThread().getName() + " 开始要执行wait操作" + " 执行了wait操作" + " -- i=" + i);
131                 wait();
132                 System.out.println(Thread.currentThread().getName() + " 执行了wait操作" + " 执行了wait操作" + " -- i=" + i);
133             } catch (InterruptedException e) {
134                 e.printStackTrace();
135             }
136         } else {
137             // 开始取钱
138             System.out.println(Thread.currentThread().getName() + " 取钱:" + drawAmount + " -- i=" + i);
139             setBalance(getBalance() - drawAmount);
140 
141             flag = false;
142 
143             // 唤醒其他线程
144             notifyAll();
145 
146             System.out.println(Thread.currentThread().getName() + "-- 取钱 -- 执行完毕" + " -- i=" + i); // 3
147         }
148     }
149 
150 }
复制代码

上面的例子演示了wait()/notify()/notifyAll()的用法。部分输出结果为:

复制代码
 1 取钱线程 开始要执行wait操作 执行了wait操作 -- i=0
 2 存钱线程 存款:700.0 -- i=0
 3 存钱线程-- 存钱 -- 执行完毕 -- i=0
 4 存钱线程 开始要执行wait操作 -- i=1
 5 取钱线程 执行了wait操作 执行了wait操作 -- i=0
 6 取钱线程 取钱:700.0 -- i=1
 7 取钱线程-- 取钱 -- 执行完毕 -- i=1
 8 取钱线程 开始要执行wait操作 执行了wait操作 -- i=2
 9 存钱线程 执行了wait操作 -- i=1
10 存钱线程 存款:700.0 -- i=2
11 存钱线程-- 存钱 -- 执行完毕 -- i=2
12 取钱线程 执行了wait操作 执行了wait操作 -- i=2
13 取钱线程 取钱:700.0 -- i=3
14 取钱线程-- 取钱 -- 执行完毕 -- i=3
15 取钱线程 开始要执行wait操作 执行了wait操作 -- i=4
16 存钱线程 存款:700.0 -- i=3
17 存钱线程-- 存钱 -- 执行完毕 -- i=3
18 存钱线程 开始要执行wait操作 -- i=4
19 取钱线程 执行了wait操作 执行了wait操作 -- i=4
20 取钱线程 取钱:700.0 -- i=5
21 取钱线程-- 取钱 -- 执行完毕 -- i=5
22 取钱线程 开始要执行wait操作 执行了wait操作 -- i=6
23 存钱线程 执行了wait操作 -- i=4
24 存钱线程 存款:700.0 -- i=5
25 存钱线程-- 存钱 -- 执行完毕 -- i=5
26 存钱线程 开始要执行wait操作 -- i=6
27 取钱线程 执行了wait操作 执行了wait操作 -- i=6
28 取钱线程 取钱:700.0 -- i=7
29 取钱线程-- 取钱 -- 执行完毕 -- i=7
30 取钱线程 开始要执行wait操作 执行了wait操作 -- i=8
31 存钱线程 执行了wait操作 -- i=6
32 存钱线程 存款:700.0 -- i=7
复制代码

由此,我们需要注意如下几点:

1.wait()方法执行后,当前线程立即进入到等待阻塞状态,其后面的代码不会执行;

2.notify()/notifyAll()方法执行后,将唤醒此同步锁对象上的(任意一个-notify()/所有-notifyAll())线程对象,但是,此时还并没有释放同步锁对象,也就是说,如果notify()/notifyAll()后面还有代码,还会继续进行,知道当前线程执行完毕才会释放同步锁对象;

3.notify()/notifyAll()执行后,如果右面有sleep()方法,则会使当前线程进入到阻塞状态,但是同步对象锁没有释放,依然自己保留,那么一定时候后还是会继续执行此线程,接下来同2;

4.wait()/notify()/nitifyAll()完成线程间的通信或协作都是基于不同对象锁的,因此,如果是不同的同步对象锁将失去意义,同时,同步对象锁最好是与共享资源对象保持一一对应关系;

5.当wait线程唤醒后并执行时,是接着上次执行到的wait()方法代码后面继续往下执行的。

当然,上面的例子相对来说比较简单,只是为了简单示例wait()/notify()/noitifyAll()方法的用法,但其本质上说,已经是一个简单的生产者-消费者模式了。

 

 

--------------------------------------------------------------------------------- 
笔者水平有限,若有错漏,欢迎指正,如果转载以及CV操作,请务必注明出处,谢谢!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值