博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java多线程通讯---------wait,notify区别
阅读量:4709 次
发布时间:2019-06-10

本文共 3927 字,大约阅读时间需要 13 分钟。

class Res{    public String username;    public String sex;}class Out extends Thread{    Res res;    public Out(Res res){        this.res=res;    }    @Override    public void run() {        //写操作        int count=0;        while (true){//            synchronized (res.getClass()){                if(count==0){//偶数                    res.username="小明";                    res.sex="男";                } else {//奇数                    res.username="小红";                    res.sex="女";                }                count=(count+1)%2;//            }            }    }}class Input extends Thread{    Res res;    public Input(Res res){        this.res=res;    }    @Override    public void run() {        while (true){//            synchronized (res.getClass()){                System.out.println(res.username+","+res.sex);//            }        }    }}public class OutInputThread {    public static void main(String[] args) {        Res res = new Res();        Out out = new Out(res);        Input input = new Input(res);        out.start();        input.start();    }}

小红,女

小红,女
小红,女
小红,女
小红,女
小红,女
小红,女
小红,女
小红,女

 

 

出现以上结果??消费者一直消费或者生产者一直生产

解决方法:生产者生产完成后消费者方可消费,否者不可消费,消费者未消费或者未消费完生产者不可生产,一次生产一次消费。其实也就是保证对res共享资源的操作同一时刻仅有同一个线程进行操作,

wait、notify、notifyAll方法

wait、notify、notifyAll是三个定义在Object类里的方法,可以用来控制线程的状态。

这三个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。

 如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。当前线程从运行变为阻塞,释放所的资源

如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。让持有该锁的线程从阻塞态变为就绪。

如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。

注意:一定要在线程同步中使用,并且是同一个锁的资源

通过以下方式即可完成需求。

生产者获取res.getClass锁后,如果flag为true生产者通过调用res.getClass.wait进行等待,此时其他线程可获取该锁,如果flag为false,进行生产,然后设置flag为true保证资源消费后方可再生产,接着通过notify通知其他唤醒其他线程。

class Res{    public String username;    public String sex;    //true 生产者等待,消费者可消费 false生产者可以生产,消费者不可消费    public boolean flag=false;}class Out extends Thread{    Res res;    public Out(Res res){        this.res=res;    }    @Override    public void run() {        //写操作        int count=0;        while (true){            synchronized (res.getClass()){                if(res.flag){                    try {                        res.getClass().wait();//让当前线程从运行变为阻塞,并且释放所的资源                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                if(count==0){//偶数                    res.username="小明";                    res.sex="男";                } else {//奇数                    res.username="小红";                    res.sex="女";                }                count=(count+1)%2;                res.flag=true;                res.getClass().notify();            }            }    }}class Input extends Thread{    Res res;    public Input(Res res){        this.res=res;    }    @Override    public void run() {        while (true){            synchronized (res.getClass()){                if(!res.flag){                    try {                        res.getClass().wait();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                System.out.println(res.username+","+res.sex);                res.flag=false;                res.getClass().notify();            }        }    }}public class OutInputThread {    public static void main(String[] args) {        Res res = new Res();        Out out = new Out(res);        Input input = new Input(res);        out.start();        input.start();    }}输出如下:小明,男小红,女小明,男小红,女小明,男小红,女小明,男小红,女

如果去掉notify会怎样?去掉一个?去掉两个?

去掉一个生产者可以打印多个(但是也不多),去掉消费者仅可打印一个,去掉两个可能不打印,也可能打印1个,所以wait、notify必须成对使用

wait(用于同步中)与sleep区别?

都是做休眠,wait需要notify

对于sleep方法,我们首先要知道该方法是属于Thread类中的。而wait方法,则是属于Object类中的。

sleep方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。

在调用sleep方法的过程中,线程不会释放对象锁。

而当调用wait方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

转载于:https://www.cnblogs.com/losemyfuture/p/9357846.html

你可能感兴趣的文章
COMP30023 Computer Systems 2019
查看>>
CSS选择器分类
查看>>
Kali学习笔记39:SQL手工注入(1)
查看>>
C# MD5加密
查看>>
Codeforces Round #329 (Div. 2)D LCA+并查集路径压缩
查看>>
移动应用开发测试工具Bugtags集成和使用教程
查看>>
Java GC、新生代、老年代
查看>>
Liferay 6.2 改造系列之十一:默认关闭CDN动态资源
查看>>
多线程
查看>>
折线切割平面
查看>>
获取当前路径下的所有文件路径 :listFiles
查看>>
图像形态学及更通用的形态学的原理及细节汇总
查看>>
linux开启coredump的3种方法
查看>>
数据驱动之 python + requests + Excel
查看>>
小鸡啄米问题求解
查看>>
Castle.net
查看>>
HDU1532 网络流最大流【EK算法】(模板题)
查看>>
PHP使用curl替代file_get_contents
查看>>
Webstorm通用设置
查看>>
jquery倾斜的动画导航菜单
查看>>