wait()和notify()

Posted toov5

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wait()和notify()相关的知识,希望对你有一定的参考价值。

从https://www.cnblogs.com/toov5/p/9837373.html 可以看到他的打印是一片一片的,这边博客介绍怎么避免掉

使用notify 和 wait的时候 要注意 是在synchronize进行的,持有同一把锁

1.因为涉及到对象锁,他们必须都放在synchronized中来使用. Wait、Notify一定要在synchronized里面进行使用。

2.Wait必须暂定当前正在执行的线程,并释放资源锁,让其他线程可以有机会运行

3. notify/notifyall: 唤醒因锁池中的线程,使之运行

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

 

一片的原因是: cpu在调度时候 读一直被调度上了

package com.toov5.thread;

//共享对象
class Res{
    public boolean flag = true;
    public String sex;
    public String name;
    
}

class inputThread extends Thread{
     public Res res;
     public inputThread(Res res) {
        this.res=res;
    }
    @Override
    public  void run() {
      int count=0; 
      while (true) {
          synchronized (res) {
               if (res.flag) {
              try {
                res.wait();   //此处一定要用res的wait!!!! 执行到这里就会阻塞了 下面的代码不会执行了  释放当前锁对象
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            }
                if (count==0) {
                    res.name="lucy";
                    res.sex="girl";    
                }else {
                    res.name="Jack";
                    res.sex="boy";
                }
                count =(count+1)%2;
                res.flag=true;  //写完了 标记当前线程为等待 然后走wait()了
                res.notify();  //通知读的线程
        }
    }
    }
}

class readThread extends Thread{
    public Res res;
    public readThread(Res res) {
        this.res=res;
    }
    
    @Override
    public void run() {
        while (true) {    
        synchronized (res) {
               if(!res.flag){
                 try {
                    res.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }    
               }
               System.out.println(res.name+","+res.sex);
               //读完了时候要 
               res.flag=false;
               res.notify();//通知写的线程
               
            }
        }        
    }
}

public class ConmunicatThreadTest {
    //开启两个线程  下面的线程 主线程 还有这俩用户线程 cpu随机的

    public static void main(String[] args) {
        Res res = new Res();
    inputThread inputThread = new inputThread(res);
    readThread  readThread = new readThread(res);
    inputThread.start();
    readThread.start();
    
    }  
       
    
}

看下结果:

技术分享图片

 

 

分析下: 

两个线程 并行在执行 假设 flag为false  读的线程会等待  cpu执行权让给写的线程同时锁也会释放掉  

                                         写的时候 读的线程发现为true (while(true)的情况) 等待notify() 被唤醒,被唤醒后 从wait处继续往下执行  唤醒被等待的线程~~~

 notifyall 是唤醒所有的  小伙伴们可以自己试试哈

 注意  notify 和 wait 一定要在synchronize里面使用!!!!!并且同一个锁对象的!  

 

wait与join 区别:

 wait需要唤醒  wait需要用在同步里面

 

wait与sleep区别

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

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

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

而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备

获取对象锁进入运行状态。

  sleep不去释放锁 wait释放

 

wait notify 为啥设计在object类 因为任意对象作为锁嘛 Object是任何类的祖宗~ 所以小伙伴们都明了了吧~~

 

以上是关于wait()和notify()的主要内容,如果未能解决你的问题,请参考以下文章

Java中 wait和await notify和signal的区别

关于wait,notify,notifyall,sleep方法的思考

多线程的wait/notify的使用

Java线程的wait(), notify()和notifyAll()

java的notify方法为啥也要同步

求求你,别再用wait和notify了!