java多线程之wait/notify/notifyAll

前言:线程的状态

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

因为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释放锁,所以其它线程能获得锁,运行结果如下。

注释掉   

 // wait(2000);

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

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唤醒了所有线程

注意:

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

猜你喜欢

转载自blog.csdn.net/u012326462/article/details/81267807