欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java多线程之wait/notify/notifyAll

程序员文章站 2022-05-04 20:53:06
...

前言:线程的状态

         Java中线程中状态可分为五类:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态),这几种状态的转换如下图

java多线程之wait/notify/notifyAll

因为wait()等方法执行时需要获得锁,所以需要monitor对象,所以要在Synchronized作用域内执行,否则会报错

 

 

wait/notity/notityAll方法的使用:

       wait()方法,将当前线程挂起,释放锁,让出cpu执行权,进入阻塞状态,方法里面加参数long timeout,如果timeout毫秒没有被唤醒,则自动唤醒。

package com.xhx.waitnotity;

import org.junit.Test;

/**
 * xuhaixing
 * 2018/7/29 9:21
 **/
public class TestApp {

    @Test
    public synchronized void testWait(){
        System.out.println(Thread.currentThread().getName()+"testWait-start-----");
        try {
            wait(2000);//等待2000毫秒,若不加参数,则一直等待,直到被notity唤醒
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"testWait-end-----");
    }



    @Test
    public void testWaitMain() throws Exception {
        TestApp testApp = new TestApp();
        for (int i = 0;i<3;i++){
            new Thread(()->testApp.testWait(),"thread"+i).start();
        }

        Thread.sleep(5000);
    }


}

上面代码用三个线程去执行,在Synchronized中,wait释放锁,所以其它线程能获得锁,运行结果如下。

java多线程之wait/notify/notifyAll

注释掉   

 // wait(2000);

运行结果是在同一个锁中顺序执行:

java多线程之wait/notify/notifyAll

 

notity()方法为唤醒一个线程

notityAll()方法为唤醒所有

因为wait是通过对象的monitor对象来实现的,所以要用同一个对象去调用notity,就可以唤醒monitor上等待的线程了

 @Test
    public synchronized void testWait2() {
        System.out.println(Thread.currentThread().getName() + "testWait-start-----");
        try {
            wait();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "testWait-end-----");
    }

    @Test
    public void testNotityMain() throws Exception {
        TestApp testApp = new TestApp();
        for (int i = 0; i < 5; i++) {
            new Thread(() -> testApp.testWait2(), "thread" + i).start();
        }
        Thread.sleep(1000);
        synchronized (testApp) {
            testApp.notify();
        }
        Thread.sleep(3000);
        System.out.println("---------");
        synchronized (testApp) {
            testApp.notifyAll();
        }
        Thread.sleep(5000);
    }

 

看下面执行结果:notify唤醒了一个线程,notifyAll唤醒了所有线程

java多线程之wait/notify/notifyAll

 

注意:

   调用wait方法会释放锁,被阻塞的线程必须要唤醒并且竞争到锁才能执行