多线程系列第(三)篇---notify和notifyAll

这三个方法都必须在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

你可能感兴趣的:(多线程系列第(三)篇---notify和notifyAll)