下面通过一个示例来演示如何使用 wait() 与notify() 来实现前面 list.size() 值等于 5 时的线程销毁
- package chapter3.test3_1.test3_1_6;
-
- import java.util.ArrayList;
- import java.util.List;
-
- public class MyList {
- private static List list = new ArrayList();
-
- public static void add() {
- list.add("anyString");
- }
-
- public static int size() {
- return list.size();
- }
- }
- package chapter3.test3_1.test3_1_6;
-
- public class ThreadA extends Thread {
- private Object lock;
-
- public ThreadA(Object lock) {
- super();
- this.lock = lock;
- }
-
- @Override
- public void run() {
- try {
- synchronized (lock) {
- if (MyList.size() != 5) {
- System.out.println("wait begin " + System.currentTimeMillis());
- lock.wait();
- System.out.println("wait end " + System.currentTimeMillis());
- }
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- package chapter3.test3_1.test3_1_6;
-
- public class ThreadB extends Thread {
- private Object lock;
-
- public ThreadB(Object lock) {
- super();
- this.lock = lock;
- }
-
- @Override
- public void run() {
- try {
- synchronized (lock) {
- for (int i = 0; i < 10; i++) {
- MyList.add();
- if (MyList.size() == 5) {
- lock.notify();
- System.out.println("已发出通知!");
- }
- System.out.println("添加了" + (i + 1) + "个元素!");
- Thread.sleep(1000);
- }
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- package chapter3.test3_1.test3_1_6;
-
- public class Run {
- public static void main(String[] args) {
- try {
- Object lock = new Object();
- ThreadA a = new ThreadA(lock);
- a.start();
- Thread.sleep(50);
- ThreadB b = new ThreadB(lock);
- b.start();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
日志信息 wait end 在最后输出,这说明notify()方法 执行后并不立即释放锁
关键字synchronized 可以将任何一个Object对象作为锁来看待,而Java为每个Object都实现了wait()和notify()方法,它们必须用在被synchronized同步的Object的临界区内。通过调用wait()方法可以使处于临界区内的线程进入等待状态,同时释放被同步对象的锁,而notify操 作可以唤醒一个因调用了wait操作而处于wait状态中的线程,使其进入就绪状态,被重新唤醒的线程会试图重新获得临界区的控制权,也就是锁,并继续执行临界区内wait之后的代码。如果发出notify操作时没有处于wait状态中的线程,那么该命令会被忽略。wait()方法可以使调用该方法的线程释放锁,然后从运行状态转换成wait状态,等待被唤醒。notify()方法按照执行wait()方法的顺序唤醒等待同一锁的“一个”线程,使其进入可运行状态,即notify()方法仅通知“一个”线程。
notifyAll()方法执行后,会按照执行wait()方法相反的顺序依次唤醒全部的线程。