java多线程wait()方法必须放在while循环里面的原因探析
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java多线程wait()方法必须放在while循环里面的原因探析,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3447字,纯文字阅读大概需要5分钟。
内容图文
![java多线程wait()方法必须放在while循环里面的原因探析](/upload/InfoBanner/zyjiaocheng/839/624f576cb8c242fa847a9746d83148a1.jpg)
1、写一个包子生产消费案例:一次生产或消费一个包子,有包子就消费,没有就生产。(部分代码参考传智播客刘意2015Java基础视频讲义)
1.1 写一个Baozi.class,包含main()方法,用来测试
package com.oy.demo3; /* * 包子生产消费案例:一次生产或消费一个包子,有包子就消费,没有就生产。 */ public class Baozi { // 默认是flag,表示没有包子,需要生产线程来生产包子;如果是true,说明有包子,需要消费端来消费包子。 public boolean flag; // 计数,当前在生产或消费第n个包子 public int count = 0; public static void main(String[] args) { // 创建共享对象 Baozi s = new Baozi(); // 在外界把共享对象创建出来,通过构造方法传递给其他的类。这样st、gt1、gt2就共享s对象。 SetThread st = new SetThread(s); GetThread gt1 = new GetThread(s); GetThread gt2 = new GetThread(s); // 线程类 Thread t1 = new Thread(st); Thread t2 = new Thread(gt1); Thread t3 = new Thread(gt2); // 启动线程 t1.start(); t2.start(); t3.start(); } }
1.2 生产包子的线程类 SetThread.class
package com.oy.demo3; public class SetThread implements Runnable { private Baozi s; public SetThread(Baozi s) { this.s = s; } @Override public void run() { while (true) { synchronized (s) { // 判断有没有 if (s.flag) { // 生产端,有就等待 try { System.out.println("生产端:等待。。。"); s.wait(); // 等待,并且立即释放锁。将来醒过来的时候,是从这里醒过来的 System.out.println("生产端:醒过来了。。。"); } catch (InterruptedException e) { e.printStackTrace(); } } // 开始生产 s.count++; System.out.println("生产第" + s.count + "包子。。。"); // 生产完后,修改标记为true s.flag = true; // 唤醒线程 s.notifyAll(); System.out.println("==========开始抢CPU的执行权=========="); } } } }
1.3 消费包子的线程类 GetThread.class
package com.oy.demo3; public class GetThread implements Runnable { private Baozi s; public GetThread(Baozi s) { this.s = s; } @Override public void run() { while (true) { synchronized (s) { while (!s.flag) { // 消费端,没有就等待 try { System.out.println(Thread.currentThread().getName() + "消费端:等待。。。"); s.wait(); // 等待,并且立即释放锁。将来醒过来的时候,是从这里醒过来的 System.out.println(Thread.currentThread().getName() + "消费端:醒过来了。。。"); } catch (InterruptedException e) { e.printStackTrace(); } } // 开始消费 System.out.println(Thread.currentThread().getName() + "消费第" + s.count + "个包子"); // 消费完了,修改标记为false s.flag = false; // 唤醒线程 s.notifyAll(); System.out.println("==========开始抢CPU的执行权=========="); } } } }
2、测试结果(只选择了控制台打印的部分结果):
==========开始抢CPU的执行权========== 生产端:等待。。。 Thread-2消费端:醒过来了。。。 Thread-2消费第6806个包子 ==========开始抢CPU的执行权========== Thread-2消费端:等待。。。 Thread-1消费端:醒过来了。。。 Thread-1消费端:等待。。。 生产端:醒过来了。。。 生产第6807包子。。。 ==========开始抢CPU的执行权==========
3、对测试结果的分析:
3.1 首先明确,生产端开启了一个线程,消费端开启了两个线程。
3.2 Thread-2消费第6806个包子,然后唤醒等待的线程;然后3个线程开始抢CPU的执行权,Thread-2消费端线程抢到了,但是此时没有包子了,所以等待;
3.3 然后,Thread-1消费端线程抢到了执行权,在原来wait()方法的地方醒过来,执行wait()方法后面的代码System.out.println(Thread.currentThread().getName() + "消费端:醒过来了。。。");然后继续while循环判断,由于此时没有包子,所以等待。如果把while改成if,就不会判断是否有包子,之间执行后面的代码消费包子,此时并没有包子了,这就产生了错误(同一个包子被消费了两次)。
3.4 综上所述:wait()方法套在while循环中,线程下次醒过来后会继续进行循环,判断条件是否满足,满足就重新等待。
3.5 由于生产端只开启了一个线程,所以将wait()方法套在if代码块中也是可以的,当然使用while也可以。
内容总结
以上是互联网集市为您收集整理的java多线程wait()方法必须放在while循环里面的原因探析全部内容,希望文章能够帮你解决java多线程wait()方法必须放在while循环里面的原因探析所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。