Java多线程学习(二)wait、notify、notifyAll详解

一、整体图表

在这里插入图片描述

二、补充知识

下图取之Java线程状态
在这里插入图片描述
如上图所示:

  1. 总共分为六个状态(运行态和就绪态归为运行态)

三、具体方法

3.1 wait方法

3.1.1定义

让线程进入等待并且释放锁。

3.1.2注意

  1. 当前线程必须持有该对象的锁
  2. wait必须被唤醒后或者设置时间进入队列才能继续执行接下来的操作

3.1.3使用方式

  public static Object object = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(new Thread1());
        thread3.start();

    }

    static class Thread1 implements Runnable {
        @Override
        public void run() {
            //比如在同步代码块或者方法里且得到该对象的锁
            synchronized (object) {
                System.out.println(Thread.currentThread().getName() + " is running.");
                try {
                    //对象进入等待
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " get the lock.");
            }
        }
    }

3.2 notify方法

3.2.1定义

唤醒任意一个等待的线程。

3.2.2注意

  1. 当前线程必须持有该对象的锁
  2. notify后会唤醒一个正在等待的线程
  3. 但是当前线程不会马上放弃锁的持有权,而是在同步代码执行完毕后才会释放锁

3.2.3 使用方式

//步骤
//1.先让线程0执行然后进行等待
//2.再让线程1执行然后通过 notify 唤醒0线程(因为等待队列只有0线程)
//3.线程1执行结束后会执行线程0
  public static Object object = new Object();
  
    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(new Thread1());
        Thread thread2 = new Thread(new Thread2());
        thread1.start();
        Thread.sleep(1000);
        thread2.start();

    }

    static class Thread1 implements Runnable {
        @Override
        public void run() {
            synchronized (object) {
                System.out.println(Thread.currentThread().getName() + "  running.");
                try {
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " get the lock.");
            }
        }
    }


    static class Thread2 implements Runnable {
        @Override
        public void run() {
            synchronized (object) {
                System.out.println(Thread.currentThread().getName() + " is running.");
                object.notify();
                System.out.println(Thread.currentThread().getName() + " invoke notify()");
                System.out.println(Thread.currentThread().getName() + " release the lock.");
            }
        }
    }

//结果:
Thread-0  running.
Thread-1 is running.
Thread-1 invoke notify()
Thread-1 release the lock.
Thread-0 get the lock.

3.3 notifyAll

3.3.1定义

唤醒所有在等待的锁。

3.3.2注意

  1. 当前线程必须持有该对象的锁
  2. notify后会唤醒所有在等待的锁
  3. 但是当前线程不会马上放弃锁的持有权,而是在同步代码执行完毕后才会释放锁

3.3.3 使用方式

步骤

  1. 先让线程0以及线程1执行然后进行等待
  2. 再让线程2执行然后通过 notifyAll 唤醒所有线程并进入终止状态(TERMINATED
  3. 线程0,1从等待状态(WAITING)进入阻塞(BLOCKED)状态
  4. 线程1获得锁进入运行状态(RUNNABLE
  5. 之后线程1进入终止状态(TERMINATED),线程0进入运行状态(RUNNABLE),之后终止(TERMINATED

执行顺序:

  public static Object object = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(new Thread1());
        Thread thread2 = new Thread(new Thread2());
        Thread thread3 = new Thread(new Thread3());
        thread1.start();
        thread2.start();
        Thread.sleep(1000);
        thread3.start();

    }

    static class Thread1 implements Runnable {
        @Override
        public void run() {
            synchronized (object) {
                System.out.println(Thread.currentThread().getName() + "  running.");
                try {
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " get the lock.");
            }
        }
    }
    static class Thread2 implements Runnable {
        @Override
        public void run() {
            synchronized (object) {
                System.out.println(Thread.currentThread().getName() + "  running.");
                try {
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " get the lock.");
            }
        }
    }

    static class Thread3 implements Runnable {
        @Override
        public void run() {
            synchronized (object) {
                System.out.println(Thread.currentThread().getName() + " is running.");
                object.notifyAll();
                System.out.println(Thread.currentThread().getName() + " invoke notifyAll()");
                System.out.println(Thread.currentThread().getName() + " release the lock.");
            }
        }
    }

结果:
Thread-0  running.
Thread-1  running.
Thread-2 is running.
Thread-2 invoke notifyAll()
Thread-2 release the lock.
Thread-1 get the lock.
Thread-0 get the lock.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章