谈谈wait()和notify()方法的使用


1、对于wait()和notify()的理解:

wait()和notify()是Object类的方法,看一下jdk官方文档给出的资料

wait():

导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。

当前的线程必须拥有此对象监视器。

notify():

唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。

直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;

直白点说:wait()就是暂停当前正在执行的线程,并释放资源锁,让其他线程可以有机会运行(程序停顿在这一行).

              :notify()就是通知等待队列中的某一个线程;

2、使用用例:生产消费者

import java.util.ArrayList;
import java.util.List;

public class ThreadDemo {
    public static void main(String[] args) {
        Pool pool = new Pool();
        Productor p1 = new Productor("生產者", pool);
        Productor p2 = new Productor("生產者", pool);
        Customer c1 = new Customer("消費者", pool);
        p1.start();
        p2.start();
        c1.start();
    }
}

//生产者
class Productor extends Thread {
    static int i = 0;
    private String name;
    private Pool pool;

    public Productor(String name, Pool pool) {
        this.name = name;
        this.pool = pool;
    }

    public void run() {
        while (true) {
            pool.add(i++);
            try {
                Thread.sleep(100);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("生产了" + i + "");
        }

    }
}

//消费者
class Customer extends Thread {
    private String name;
    private Pool pool;

    public Customer(String name, Pool pool) {
        this.name = name;
        this.pool = pool;
    }

    public void run() {
        while (true) {
            int i = pool.remove();
            try {
                Thread.sleep(100);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("消费了" + i);
        }
    }
}


//生产 删除方法类
class Pool {
    private List<Integer> list = new ArrayList<Integer>();
    //容量最大值
    private int Max = 100;//防止栈溢出,到达100等待

    //添加元素
    public void add(int n) {
        synchronized (this) {
            try {
                while (list.size() >= Max) {
                    this.wait();
                }
                list.add(n);
                System.out.println("size ==" + list.size());
                this.notify();

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    //刪除元素
    public int remove() {
        synchronized (this) {
            try {
                while (list.size() == 0) {
                    this.wait();
                }
                int i = list.remove(0);
                this.notify();
                return i;

            } catch (Exception e) {
                e.printStackTrace();
            }
            return -1;
        }
    }

}

3、需要特殊注意的地方    

  • 当需要调用wait()和notify()方法时,一定要对竞争资源进行加锁,如果不加锁会报java.lang.IllegalMonitorStateException 异常;
  • 消费者被唤醒后是从wait()方法后面执行,而不是重新从同步块开始;

                                                                                                               翻过那座山,世界会看到你  --------作者:刘村长 

猜你喜欢

转载自blog.csdn.net/qq_36523209/article/details/85203915
今日推荐