sleep和wait

  1. sleep是Thread类的方法,wait是Object的方法。
  2. sleep可以到处使用,wait必须是在同步方法或者代码块里使用,不然会有java.lang.IllegalMonitorStateException异常。
  3. sleep不释放持有的锁,wait释放锁。wait在调用方法前,必须持有锁,调用notify,notifyall唤醒,也要持有锁。
  4. sleep休眠一定时间后,进入就绪状态。wait由notify和notifyall唤醒。这两个都能被interrupt方法中断当前状态。

join和yield

这两个和sleep一样,不释放持有的锁。

示例

public class WaitDemo {    private String tv = "广告";    static class Tv extends Thread {        WaitDemo waitDemo;        public Tv(WaitDemo waitDemo) {            this.waitDemo = waitDemo;        }        @Override        public void run() {            waitDemo.waitTv();        }    }    public synchronized void waitTv() {        while (tv.equals("广告")) {            try {                wait();                if (tv.equals("广告")) {                    System.out.println(Thread.currentThread().getName() + "-" + "骗人,还是广告");                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }        System.out.println(Thread.currentThread().getName() + "-" +"愉快的追剧");    }    public synchronized void sendTrueMsg() {        tv = "正剧";        notifyAll();    }    public synchronized void sendFalseMsg() {        notifyAll();    }    public static void main(String[] args) throws InterruptedException {        WaitDemo waitDemo = new WaitDemo();        Tv tv1 = new Tv(waitDemo);        Tv tv2 = new Tv(waitDemo);        tv1.start();        tv2.start();        Thread.sleep(100);        waitDemo.sendFalseMsg();        Thread.sleep(100);        waitDemo.sendTrueMsg();    }}

运行的结果如下:

例子:大部分人喜欢看连续剧,但是不看广告(没钱买VIP),于是就让别人提醒她广告结束了没有,如果结束了,就提醒她。
用法:

wait方

  1. 获取锁
  2. while判断条件,不满足继续wait
  3. 满足执行其他业务

notify方

  1. 获取锁
  2. 改变条件
  3. 通知

为什么是while而不是if

while会一直循环,直到条件满足。如果是if,只会判断一次,如果不满足条件,会一直等待

为什么是notifyAll而不是notify

可以把上面的例子,改成notify,那么进程永远不会结束,因为在多线程情况下,notify只能唤醒随机的一个休眠线程,其他已休眠的线程不能唤醒,造成信号不能传达而丢失,而notifyAll可以唤醒所有的。