(四)wait()、notify()、notifyAll()方法||wait()与sleep()的区别
来源:互联网 发布:天天特价淘宝网童装 编辑:程序博客网 时间:2024/05/22 08:06
wait()、notify()、notifyAll()方法
wait()与sleep()的区别
一、wait()、notify()、notifyAll()方法
方法介绍
wait()、notify()、notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态。
这三个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。
如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。
如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。
如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。注意:这三个方法一定要在线程同步中使用,并且是同一个锁的资源
思考上个文章里面出现的问题(三)
/**
* 为何打印出来的数据不是小红一个、大圣一个;而是批量的小红以及批量的大圣?
* 解决办法:
* 生产者线程生产一个,消费者马上消费,消费者没有消费完毕,生产者不能继续生产;
* 生产者没有生产,消费者不能读;
*/
代码实战:
共享资源源实体类
/** 共享资源源实体类 */class UserInfo { public String userSex; public String userName; /**线程通讯标识 * true:让生产者进行等待,消费者进行消费 * false:生产者可以生产,消费者进行等待 * */ public boolean flag=false;}
输入线程资源
public class InputThread extends Thread{ private UserInfo user; //构造函数 public InputThread (UserInfo user){ this.user=user; } @Override public void run() { int count=0; while (true){ //解决线程不安全问题,在出现线程安全的代码块上加synchronized关键字 synchronized (user) { //当flag为true时(注意:在判断条件里if(user.flag)等价于if(user.flag==true)) if (user.flag) { try { //让当前线程 从运行状态变为休眠状态,并且释放锁的资源 user.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //1.当线程第一次运行时,flag为false,先进行生产 if(count==0){ user.userName="大圣"; user.userSex="男"; }else{ user.userName="小红"; user.userSex="女"; } //计算奇数或者偶数公式 count=(count+1)%2; //2.当第一个线程生产完的时候,把flag状态改为true, // 即让生产者线程处于等待状态,让消费者进行读取 user.flag=true; //唤醒当前等待的线程,否则你只能打印一条 user.notify(); } } }
输出线程资源
public class OutputThread extends Thread{ private UserInfo user; //构造函数 public OutputThread(UserInfo user){ this.user=user; } @Override public void run() { while (true) { //解决线程不安全问题,在出现线程安全的代码块上加synchronized关键字 synchronized (user) { //当flag为false时(注意:在判断条件里if(!user.flag)等价于if(user.flag==false)) if (!user.flag) { try { //让当前线程 从运行状态变为休眠状态,并且释放锁的资源 user.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //3.进来时,flag为true,消费者进行消费,生产者进行等待 System.out.println("userName:"+user.userName+"----userSex:"+user.userSex); //4.消费者读取完后,把flag状态改为false,再去生产者那边生产,待在消费者这里也没用 user.flag=false; //唤醒当前等待的线程,否则你只能打印一条 user.notify(); } } }}
运行代码:
UserInfo user=new UserInfo(); //构造方法就是在这里用的 //两个线程共享同一变量 InputThread it=new InputThread(user); OutputThread ot=new OutputThread(user); it.start(); ot.start();
运行结果:
运行结果正常:偶数打印打印大圣,奇数打印小红,不再批量打印了
二、wait与sleep的区别是什么?
相同点:
- 都是做休眠
不同点:
这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。
sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用了b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。
最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
sleep不出让系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。一般wait不会加时间限制,因为如果wait线程的运行资源不够,再出来也没用,要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。
sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间不到只能调用interrupt()强行打断。
Thread.Sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。
使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
synchronized(x){
x.notify()
//或者wait()
}sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
- (四)wait()、notify()、notifyAll()方法||wait()与sleep()的区别
- wait、sleep、notify、notifyAll的区别
- wait、sleep、notify、notifyAll的区别
- wait、sleep、notify、notifyAll的区别
- wait、sleep、notify、notifyAll的区别
- wait、sleep、notify、notifyAll的区别
- wait(),notify(),notifyAll()及sleep() 和wait()的区别
- wait(),notify(),notifyAll()及sleep() 和wait()的区别
- sleep & wait | notify | notifyAll
- sleep & wait | notify | notifyAll
- wait,notify,notifyAll,sleep
- sleep,yield,join,notify,wait,notifyAll区别
- sleep() yield() wait() notify() notifyAll()方法
- sleep synchronized wait notify notifyAll
- synchronized,sleep,wait,notify,notifyAll
- Java:sleep、wait、notify、notifyAll
- 多线程wait-notify;notifyall.sleep
- wait|notify|notifyAll|sleep|volatile
- Warning Setting property 'source' to 'org.eclipse.jst.jee.server的问题
- 理解伯德图-2/4什么是伯德图
- JS实现复选框的全选和批量删除功能(php后端)
- Thrift 客户端 Python
- 学习网站
- (四)wait()、notify()、notifyAll()方法||wait()与sleep()的区别
- AngualrJS的学习记录(二)
- 解决Android运行过程中出现的NoClassDefFoundError
- [堆与斜率] Codeforces 713C
- Linux ssh ftp 用户访问权限
- jtopo 实现调用saveImageInfo()方法直接下载图片,支持所有浏览器
- ebay_展示图片抓取
- JAVA程序员必看的15本书-JAVA自学书籍推荐
- Xcode里的-ObjC,-all_laod和-force_load的作用