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)池和等待池。