这三个方法都必须在synchronized方法或者synchronized块中使用,否则会抛异常java.lang.IllegalMonitorStateException
wait
放弃当前资源的占有权,等啊等,直到有人通知我,才会运行wait之后的代码
notify和notifyAll
notify,唤醒一个正在等待该对象的线程。
notifyAll,唤醒所有正在等待该对象的线程。
两者相同点
都只是让线程退出等待状态,退出等待状态的线程仍然需要等待对象锁的释放
两者的不同点
前者只是通知一个线程(至于是哪个线程就看JVM了),后者是通知所有的线程。
只有被通知的线程才有机会在拿到锁之后执行wait之后的代码。
notify代码示例
public class NotifyDemo {
public synchronized void waitMethod(String name) {
System.out.println(name + " begin");
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + " end");
}
public synchronized void notifyMethod(String name) {
System.out.println(name + " begin");
notify();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + " end");
}
class WaitThread extends Thread {
private NotifyDemo notifyDemo;
public WaitThread(String name, NotifyDemo notifyDemo) {
super(name);
this.notifyDemo = notifyDemo;
}
public void run() {
notifyDemo.waitMethod(getName());
}
}
class NotifyThread extends Thread {
private NotifyDemo notifyDemo;
public NotifyThread(String name, NotifyDemo notifyDemo) {
super(name);
this.notifyDemo = notifyDemo;
}
public void run() {
notifyDemo.notifyMethod(getName());
}
}
public static void main(String[] args) {
NotifyDemo demo = new NotifyDemo();
WaitThread t1 = demo.new WaitThread("等待线程1", demo);
WaitThread t2 = demo.new WaitThread("等待线程2", demo);
NotifyThread t3 = demo.new NotifyThread("唤醒线程3", demo);
t1.start();
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t3.start();
}
}
运行结果
等待线程1 begin
等待线程2 begin
唤醒线程3 begin
唤醒线程3 end
等待线程1 end
notifyAll代码示例
public class NotifyAllDemo {
public synchronized void waitMethod(String name) {
System.out.println(name + " begin");
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + " end");
}
public synchronized void notifyMethod(String name) {
System.out.println(name + " begin");
notifyAll();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + " end");
}
class WaitThread extends Thread {
private NotifyAllDemo notifyDemo;
public WaitThread(String name, NotifyAllDemo notifyDemo) {
super(name);
this.notifyDemo = notifyDemo;
}
public void run() {
notifyDemo.waitMethod(getName());
}
}
class NotifyThread extends Thread {
private NotifyAllDemo notifyDemo;
public NotifyThread(String name, NotifyAllDemo notifyDemo) {
super(name);
this.notifyDemo = notifyDemo;
}
public void run() {
notifyDemo.notifyMethod(getName());
}
}
public static void main(String[] args) {
NotifyAllDemo demo = new NotifyAllDemo();
WaitThread t1 = demo.new WaitThread("等待线程1", demo);
WaitThread t2 = demo.new WaitThread("等待线程2", demo);
NotifyThread t3 = demo.new NotifyThread("唤醒线程3", demo);
t1.start();
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t3.start();
}
}
运行结果
等待线程1 begin
等待线程2 begin
唤醒线程3 begin
唤醒线程3 end
等待线程2 end
等待线程1 end
网友评论