Java Thread wait, notify and notifyAll Example

本文介绍了Java类对象中用于进程间通知锁定状态资源的wait()、notify()和notifyAll()方法。阐述了各方法的作用、状态变化及使用时需持有对象锁的要求,还说明了这些方法在生产消费者问题中的应用,并给出相关示例类及测试结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  在java类的对象中包含了三个方法,允许进程间相互通知锁定状态的资源。这三个方法是wait(),notify()和notifyAll();

  任何一个调用这些方法的对象都必须持有该对象的一个对象锁,否则的话,会抛出java.lang.IllegalMonitorStateException异常

Wait

  wait方法有三个状态的变化。一个是无限期的等待任何一个线程来调用所持有的对象的notify或者是notifyAll 方法来唤醒当前线程。另外两个变化是将当前的线程等待特定的时间再到唤醒状态

Notify

 notify方法只会唤醒一个处于等待状态的该对象,然后是对应的线程开始继续运行。因此,当一个对象有很多歌线程处于等待状态的时候,这个方法只会唤醒他们其中的一个。至于唤醒哪一个,这就取决于操作系统的线程管理了。

notifyAll

 该方法会唤醒对象的所有的处于等待状态的线程。哪一个先处理这同样取决于操作系统


这些方法可以被用到生产消费者问题上。消费者线程一是在队列中一直处于等待状态,而生产者则是往队列中放入对象,并且通知消费者。

下面是一个例子,有多个线程工作在同一个对象上。


Message

 一个java bean类,我们让线程工作在这个对象的wait和notfify方法上

Message.java


package com.journaldev.concurrency;
 
public class Message {
    private String msg;
     
    public Message(String str){
        this.msg=str;
    }
 
    public String getMsg() {
        return msg;
    }
 
    public void setMsg(String str) {
        this.msg=str;
    }
 
}

Waiter

  该类将会等待其他的线程来调用notify方法来继续完成该线程的处理工作。需要注意的是,该waiter对象是拥有一个对象message的锁的,因为它使用了同步块

Waiter.java

package com.journaldev.concurrency;
 
public class Waiter implements Runnable{
     
    private Message msg;
     
    public Waiter(Message m){
        this.msg=m;
    }
 
    @Override
    public void run() {
        String name = Thread.currentThread().getName();
         //进行同步块操作
           synchronized (msg) {
            try{
                System.out.println(name+" waiting to get notified at time:"+System.currentTimeMillis());
                msg.wait();//执行此方法之后,该线程就开始等待
            }catch(InterruptedException e){
                e.printStackTrace();
            }
           //线程被唤醒,继续完成没有执行完的程序
            System.out.println(name+" waiter thread got notified at time:"+System.currentTimeMillis());
            System.out.println(name+" processed: "+msg.getMsg());
        }
    }
 
}

Notifier

   该方法将会处理message对象,并调用notify方法来唤醒message对象正在等待的线程。和wiater一样,利用同步块来获取该对象的锁


Notifier.java

package com.journaldev.concurrency;
 
public class Notifier implements Runnable {
 
    private Message msg;
     
    public Notifier(Message msg) {
        this.msg = msg;
    }
 
    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        System.out.println(name+" started");
        try {
            Thread.sleep(1000);
            synchronized (msg) {
                msg.setMsg(name+" Notifier work done");
                msg.notify();
                // msg.notifyAll();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
         
    }
 
}

WaitNotifyTest

测试类,该类将创建对个线程并且启动他们

WaitNotifyTest.java

package com.journaldev.concurrency;
 
public class WaitNotifyTest {
 
    public static void main(String[] args) {
        Message msg = new Message("process it");
        Waiter waiter = new Waiter(msg);
        new Thread(waiter,"waiter").start();
         
        Waiter waiter1 = new Waiter(msg);
        new Thread(waiter1, "waiter1").start();
         
        Notifier notifier = new Notifier(msg);
        new Thread(notifier, "notifier").start();
        System.out.println("All the threads are started");
    }
 
}

执行上面的测试类,将会看到下面的输出。因为对象 msg有两个等待的线程,而调用了notify方法,只唤醒了他们其中的一个,另外一个还在继续等待被唤醒。

notify()

waiter waiting to get notified at time:1356318734009
waiter1 waiting to get notified at time:1356318734010
All the threads are started
notifier started
waiter waiter thread got notified at time:1356318735011
waiter processed: notifier Notifier work done

当打开注释,并且将notify注释后,会看到如下的输出

notifyall()

waiter waiting to get notified at time:1356318917118
waiter1 waiting to get notified at time:1356318917118
All the threads are started
notifier started
waiter1 waiter thread got notified at time:1356318918120
waiter1 processed: notifier Notifier work done
waiter waiter thread got notified at time:1356318918120
waiter processed: notifier Notifier work done

这是因为notifyall()方法会唤醒所有的处于等待状态的线程让他们执行没有完成的工作


原文:http://www.journaldev.com/1037/java-thread-wait-notify-and-notifyall-example





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值