wait() 和notify() 怎么使用 6个demo诠释它+3个demoZH

java面试题网站:www.javaoffers.com

demo1:

package com.jvm.others.thread;
/**测试Wait和notify的搭配使用
 * @author pc
 *
 */
public class WaitAndNotify {
public static void main(String[] args) throws Exception {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("THread1开始Waiting");
   try {
    synchronized (this) {//thread1对象
    wait();
}
System.out.println("THread1结束Waiting");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});

        Thread thread2 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("thread2开始调用notify");
synchronized (this) {//thread2对象
notify();
}

}
});

        thread1.start();
        Thread.sleep(2000);
        thread2.start();
        //运行的结果是:
        //THread1开始Waiting
        //thread2开始调用notify
}
}

demo2:

package com.jvm.others.thread;
public class WaitAndNotify2 {
public static void main(String[] args) throws Exception {
     
Thread thread1 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("THread1开始Waiting");
   try {
    synchronized (this) {//thread1对象
    wait();
}

System.out.println("THread1结束Waiting");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});

        Thread thread2 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("thread2开始调用notify");
synchronized (this) {//thread2对象
notifyAll();
}

}
});

        thread1.start();
        Thread.sleep(2000);
        thread2.start();
      //运行的结果是:
      //THread1开始Waiting
      //thread2开始调用notify
}
}

demo3:

package com.jvm.others.thread;
public class WaitAndNotify3 {

public static void main(String[] args) throws Exception {

   final WaitAndNotify3 waitAndNotify3 = new WaitAndNotify3();  //创建一个waitAndNotify3对象,让Thread1和Thread2的同步代码块都拥有同一个 waitAndNotify3对象
   
Thread thread1 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("THread1开始Waiting");
   try {
    synchronized (waitAndNotify3) {//waitAndNotify3对象
    wait();
}

System.out.println("THread1结束Waiting");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});

        Thread thread2 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("thread2开始调用notify");
synchronized (waitAndNotify3) {//waitAndNotify3对象
notifyAll();
}

}
});

        thread1.start();
        Thread.sleep(2000);
        thread2.start();
      //运行的结果是:
        /**
       * THread1开始Waiting
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:503)
at com.jvm.others.thread.WaitAndNotify3$1.run(WaitAndNotify3.java:16)
at java.lang.Thread.run(Thread.java:745)
thread2开始调用notify
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at com.jvm.others.thread.WaitAndNotify3$2.run(WaitAndNotify3.java:33)
at java.lang.Thread.run(Thread.java:745)
       */
}
}

demo4:

package com.jvm.others.thread;


public class WaitAndNotify4 {
static final WaitAndNotify4 waitAndNotify3 = new WaitAndNotify4();  //创建一个waitAndNotify3对象,让Thread1和Thread2的同步代码块都拥有同一个 waitAndNotify3对象
public static void main(String[] args) throws Exception {

  
   
Thread thread1 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("THread1开始Waiting");
   try {
    synchronized (waitAndNotify3) {//thread1对象
    waitAndNotify3.wait();
}

System.out.println("THread1结束Waiting");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});

        Thread thread2 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("thread2开始调用notify");
synchronized (waitAndNotify3) {//thread2对象
waitAndNotify3.notify();//waitAndNotify3.notify();

}
 
}
});

        thread1.start();
        Thread.sleep(2000);
        thread2.start();
      //运行的结果是:
     /**
      * THread1开始Waiting
        thread2开始调用notify
        THread1结束Waiting
      */
}

}

demo5:

package com.jvm.others.thread;


public class WaitAndNotify5 {
static final WaitAndNotify5 waitAndNotify3 = new WaitAndNotify5();  //创建一个waitAndNotify3对象,让Thread1和Thread2的同步代码块都拥有同一个 waitAndNotify3对象
public static void main(String[] args) throws Exception {

  
   
Thread thread1 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("THread1开始Waiting");
   try {
    synchronized (waitAndNotify3) {//thread1对象
    waitAndNotify3.wait();
}

System.out.println("THread1结束Waiting");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});

        Thread thread2 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("thread2开始调用notify");
synchronized (waitAndNotify3) {//thread2对象
waitAndNotify3.notify();//waitAndNotify3.notify();

}
 
}
});

       Thread thread3 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("thread3开始调用Waiting");
synchronized (waitAndNotify3) {//thread2对象
try {
waitAndNotify3.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//waitAndNotify3.notify();
System.out.println("THread3结束Waiting");
}
 

});
        
        thread1.start();
        thread3.start();
        
        Thread.sleep(2000);
        thread2.start();
      //运行的结果是:
     /**
       * thread3开始调用Waiting
         THread1开始Waiting
         thread2开始调用notify
         THread3结束Waiting
      */
}

}

demo6:

package com.jvm.others.thread;


public class WaitAndNotify6 {
static final WaitAndNotify6 waitAndNotify3 = new WaitAndNotify6();  //创建一个waitAndNotify3对象,让Thread1和Thread2的同步代码块都拥有同一个 waitAndNotify3对象
public static void main(String[] args) throws Exception {

  
   
Thread thread1 = new Thread(new Runnable() {

@Override
public void run() {

Thread thread1Inner = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("thread1Inner开始Waiting");

   try {
    synchronized (waitAndNotify3) {//thread1对象
    waitAndNotify3.wait();
}

System.out.println("thread1Inner结束Waiting");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
thread1Inner.start();
System.out.println("THread1开始Waiting");
   try {
    synchronized (waitAndNotify3) {//thread1对象
    waitAndNotify3.wait();
}

System.out.println("THread1结束Waiting");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});

        Thread thread2 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("thread2开始调用notifyAll");
synchronized (waitAndNotify3) {//thread2对象
waitAndNotify3.notifyAll();//waitAndNotify3.notify(); 
 
}
 
}
});

       Thread thread3 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("thread3开始调用Waiting");
synchronized (waitAndNotify3) {//thread3对象
try {
waitAndNotify3.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//waitAndNotify3.notify();
System.out.println("THread3结束Waiting");
}
 

});
        thread1.start();//线程一启动后线程一内部再启动和线程一一样的逻辑
        thread3.start();
        
        Thread.sleep(2000);
        thread2.start();
      //运行的结果是:
     /**
       * thread3开始调用Waiting
         THread1开始Waiting
         thread1Inner开始Waiting
         thread2开始调用notifyAll
         thread1Inner结束Waiting
         THread3结束Waiting
         THread1结束Waiting
      */
}
}

demoZH01:

package com.jvm.others.thread;


public class WaitAndNotifyZH {

public static void main(String[] args) throws Exception {
   
Thread thread1 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("THread1开始Waiting");
   try {
    synchronized (StaticObject.obj) {//thread1对象
    StaticObject.obj.wait();
}

System.out.println("THread1结束Waiting");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
        thread1.start();
}

}

demoZH02:

package com.jvm.others.thread;


public class WaitAndNotifyZH2 {

public static void main(String[] args) throws Exception {

  
   
Thread thread2 = new Thread(new Runnable() {

@Override
public void run() {
System.out.println("THread1开始Waiting");
   try {
    synchronized (StaticObject.obj) {//thread1对象
    StaticObject.obj.wait();
}

System.out.println("THread1结束Waiting");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
        thread2.start();
}

}

demoZH03:

package com.jvm.others.thread;


public class WaitAndNotifyZH3 {

public static void main(String[] args) throws Exception {

  
   
Thread thread1 = new Thread(new Runnable() {

@Override
public void run() {
 
   try {
    synchronized (StaticObject.obj) {//thread1对象
    StaticObject.obj.notifyAll();
}
System.out.println("调用了notifyAll");

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
        thread1.start();
      
       
      //运行的结果是:

           //demoZH01线程没有结束

           //demoZH02线程也没有结束

}
}

总结:

wait() 和notify() 或者 notifyAll() 进行搭配的时候必须在synchronized(obj)模块里  (注:这里的obj为任意一对象),

切调用wait() notify(),notifyAll()的对象要同一(注:为相同的对象。)

wait() notify(),notifyAll()这三个方法的作用范围:必须在同一个main方法里,否者无效。(请看demoZH01,demoZH02,demoZH02).

调用notify()时:恢复第一个调用wait()方法的线程,其他的线程不恢复。(注:每个调用wait()方法的对象要同一,即都是相同的一个对象。调用notify()方法的对象  和  调用wait()方法的对象    要一样)

调用notifyAll()时:恢复所有调用wait()方法的线程。(注:每个调用wait()方法的对象要同一,即都是相同的一个对象。调用notifyAll()方法的对象  和  调用wait()方法的对象    要一样) 

调用wait方法时:会释放当前的锁对象并加入该对象的等待池中。只有针对此对象调用notify()或者notifyAll()方法后本线程才进入对象锁池准备竞争对象锁 当锁池中的线程获得锁后,才开始准备恢复执行操作(这也是必须在synchronized(obj)模块里的原因,当线程唤醒后已经获得了对象锁,并且此时的线程处于synchronized(obj)模块里,假如线程没有在synchronized(obj)模块里,那锁对象所对应的线程进入到锁池中并获得锁 就没有意义了。同时java语言规定 wait() notify(),notifyAll()要在 在synchronized(obj)模块里使用,否者会报错的)。在java中,每个对象都有两个池,锁(monitor)池和等待池。

3:注意: 线程的等待与唤醒都与所关联的对象有关, 因为他们依赖 关联对象的两个池,锁(monitor)池和等待池。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值