• Java多线程中wait, notify and notifyAll的使用


    本文为翻译文章,原文地址:http://www.journaldev.com/1037/java-thread-wait-notify-and-notifyall-example

    在Java的Object类中有三个final的方法同意线程之间进行资源对象锁的通信,他们各自是: wait(), notify() and notifyAll()。

    调用这些方法的当前线程必须拥有此对象监视器。否则将会报java.lang.IllegalMonitorStateException exception异常。

    wait

    Object的wait方法有三个重载方法,当中一个方法wait() 是无限期(一直)等待,直到其他线程调用notify或notifyAll方法唤醒当前的线程;另外两个方法wait(long timeout) 和wait(long timeout, int nanos)同意传入 当前线程在被唤醒之前须要等待的时间,timeout为毫秒数,nanos为纳秒数。

    notify

    notify方法仅仅唤醒一个等待(对象的)线程并使该线程開始运行。

    所以假设有多个线程等待一个对象,这种方法仅仅会唤醒当中一个线程,选择哪个线程取决于操作系统对多线程管理的实现。

    notifyAll

    notifyAll 会唤醒全部等待(对象的)线程,虽然哪一个线程将会第一个处理取决于操作系统的实现。

    这些方法能够使用于“生产者-消费者”问题,消费者是在队列中等待对象的线程,生产者是在队列中释放对象并通知其他线程的线程。

    让我们来看一个多线程作用于同一个对象的样例。我们使用wait, notify and notifyAll方法。


    通过实例来理解

    Message

    一个java bean类。线程将会使用它并调用wait和notify方法。

    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

    一个Waiter类,等待其他的线程调用notify方法以唤醒线程完毕处理。

    注意等待线程必须通过加synchronized同步锁拥有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());
                //process the message now
                System.out.println(name+" processed: "+msg.getMsg());
            }
        }
    
    }

    Notifier

    一个Notifier类,处理Message对象并调用notify方法唤醒等待Message对象的线程。

    注意synchronized代码块被用于持有Message对象的监视器。

    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");
        }
    
    }

    当我们调用以上的代码时能够看到下面的输出。但并没有结束(完毕),由于有两个线程等待同一个Message对象。但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 Notifying work done
    

    假设我们凝视掉Notifier类中的notify() 方法的调用,并打开notifyAll() 方法的调用,将会有下面的输出信息。

    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 Notifying work done
    waiter waiter thread got notified at time:1356318918120
    waiter processed: notifier Notifying work done
    

    一旦notifyAll()方法唤醒全部的Waiter线程。程序将会运行完毕并退出。

  • 相关阅读:
    NYOJ 527 AC_mm玩dota
    程序员励志小说链接
    android——ListView功能的实现
    调用系统工具
    HDU SPFA算法 Invitation Cards
    nginx sendfile tcp_nopush tcp_nodelay参数解释
    结构体中使用#define定义宏
    HRPlugin For Xcode发布(附源码地址)
    Derby的下载安装和使用,(和JAVA中使用Derby)
    UNIX环境高级编程——进程管理和通信(总结)
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5064776.html
Copyright © 2020-2023  润新知