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是任何类的祖宗~ 所以小伙伴们都明了了吧~~