线程的等待和通知及示例代码(waitnotifynotifyAll)

Posted 零

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程的等待和通知及示例代码(waitnotifynotifyAll)相关的知识,希望对你有一定的参考价值。

线程的等待和通知

Object类的方法:

  • void wait():让持有锁的线程进入等待状态,直到被通知
  • void wait(long time):让线程等待,直到被通知或时间结束
  • void notify():随机选择一个等待的线程,进行通知
  • void notifyAll():通知所有等待的线程

注意:上面的方法只能是锁对象调用,否则出现异常IllegalMonitorStateException

yieId sleep 不释放锁,wait notify 在执行的时候释放锁,无论是notify还是notifyAll,都必须要写在方法体的最后一样,如果不是,无法释放锁

示例代码

public class Express 
    public final static String CITY = "ShangHai";
    private int km; // 快递运输里程数
    private String site; // 快递到达地点

    public Express() 
    

    public Express(int km, String site) 
        this.km = km;
        this.site = site;
    

    // 变化公里数,然后通知处于wait状态并需要处理公里数的线程进行业务处理
    public synchronized void changeKm() 
        this.km = 101;
        notifyAll();
        //其他的业务代码

    

    // 变化地点,然后通知处于wait状态并需要处理地点的线程进行业务处理
    public synchronized void changeSite() 
        this.site = "BeiJing";
        notify();
    

    public synchronized void waitKm() 
        while (this.km <= 100) 
            try 
                wait();
                System.out.println("check km 线程[" + Thread.currentThread().getId()
                                   + "] 被通知");
             catch (InterruptedException e) 
                e.printStackTrace();
            
        
        System.out.println("快递运输里程数发生改变,当前公里数:" + this.km);

    

    public synchronized void waitSite() 
        while (CITY.equals(this.site)) 
            try 
                wait();
                System.out.println("check site 线程[" + Thread.currentThread().getId()
                                   + "] 被通知");
             catch (InterruptedException e) 
                e.printStackTrace();
            
        
        System.out.println("快递位置发生改变,到达" + this.site);
    

public class TestWN 
    private static Express express = new Express(0, Express.CITY);

    // 检查里程数变化的线程,不满足条件,线程一直等待
    private static class CheckKm extends Thread 
        @Override
        public void run() 
            express.waitKm();
        
    

    // 检查地点变化的线程,不满足条件,线程一直等待
    private static class CheckSite extends Thread 
        @Override
        public void run() 
            express.waitSite();
        
    

    public static void main(String[] args) throws InterruptedException 
        for (int i = 0; i < 3; i++) //三个线程
            new CheckSite().start();
        
        for (int i = 0; i < 3; i++) //里程数的变化
            new CheckKm().start();
        

        Thread.sleep(1000);
        express.changeKm();//快递地点变化
    

以上是关于线程的等待和通知及示例代码(waitnotifynotifyAll)的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程之三volatile与等待通知机制示例

通知线程是不是可以在被通知线程等待锁定之前锁定?

java线程的等待通知机制读书笔记

多线程之Condition的await和signalsignalAll等待/通知机制

Java并发包1--线程的状态及常用方法

Java并发编程之十二:线程间通信中notifyAll造成的早期通知问题(含代码)