Object类中wait带参方法和notifyAll方法
查看Object类的API文档可以看到,除了无参方法wait之外,类中还有重载的有参wait方法:
以及一个 notifyAll方法:
进入到Timed_Waiting(计时等待)状态有两种方式:
1.sleep(long m)方法,在毫秒值结束之后,线程睡醒,进入到Runnable或BLocked状态。
2.使用wait(long m)方法,wait方法如果在毫秒结束之后,还没有被notify,就会自动醒来,进入到Runnable或BLocked状态。(区别:直接wait无参,是进入waiting无限等待状态,有参是进入Timed_Waiting限时等待状态中)
public static void main(String[] args) { // 创建锁对象,保证唯一 Object obj = new Object(); // 创建一个顾客线程 // 使用匿名内部类,这样就不用写继承父类的子类,或实现接口的实现类 new Thread(new Runnable() { @Override public void run() { // 保证等待和唤醒只能有一个在执行 // 所以需要使用同步代码块 while (true) { // 死循环 synchronized (obj) { // 告知老板需要的包子种类和数量 System.out.println("告知老板需要的包子种类和数量"); // 调用监视器锁的wait方法,进入waiting状态 try { // 捕捉异常 // 5000毫秒之后,无notify唤醒,自动醒 obj.wait(5000L); } catch (InterruptedException e) { e.printStackTrace(); } // 唤醒之后的操作 System.out.println("包子做好了,开吃!"); System.out.println("------------"); } } } }).start(); // 执行 }
唤醒方法,也一共有两个方法:
1.notify方法唤醒在此对象监视器上等待的单个线程。
2.notifyAll方法唤醒在此对象监视器上等待的所有线程。
public static void main(String[] args) { // 创建锁对象,保证唯一 Object obj = new Object(); // 创建一个顾客线程 // 使用匿名内部类,这样就不用写继承父类的子类,或实现接口的实现类 new Thread(new Runnable() { @Override public void run() { // 保证等待和唤醒只能有一个在执行 // 所以需要使用同步代码块 while (true) { // 死循环 synchronized (obj) { // 告知老板需要的包子种类和数量 System.out.println("顾客1告知老板需要的包子种类和数量"); // 调用监视器锁的wait方法,进入waiting状态 try { // 捕捉异常 // 5000毫秒之后,无notify唤醒,自动醒 obj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } // 唤醒之后的操作 System.out.println("包子做好了,顾客1开吃!"); System.out.println("------------"); } } } }).start(); // 执行 // 创建第二个顾客线程 new Thread(new Runnable() { @Override public void run() { // 保证等待和唤醒只能有一个在执行 // 所以需要使用同步代码块 while (true) { // 死循环 synchronized (obj) { // 告知老板需要的包子种类和数量 System.out.println("顾客2告知老板需要的包子种类和数量"); // 调用监视器锁的wait方法,进入waiting状态 try { // 捕捉异常 // 5000毫秒之后,无notify唤醒,自动醒 obj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } // 唤醒之后的操作 System.out.println("包子做好了,顾客2开吃!"); System.out.println("------------"); } } } }).start(); // 执行 // 创建一个老板线程(生产者) new Thread(new Runnable() { @Override public void run() { // 同步代码块 while (true) { // 唤醒顾客,吃包子 try { // 花5秒做包子 Thread.sleep(5000L); // long型 } catch (InterruptedException e) { e.printStackTrace(); } synchronized (obj) { System.out.println("5秒到了。包子做好了!"); obj.notify(); // 如果有多个线程在等待,随机唤醒一个 obj.notifyAll(); // 唤醒所有等待线程,方便同步! } } } }).start(); }