java多线程中等待/通知机制

来源:互联网 发布:网络诈骗员工怎么处理 编辑:程序博客网 时间:2024/06/03 20:07

一个线程做了修改对象值(或其他)操作,另一个线程感知到了变化,然后进行相应操作,整个过程开始于一个线程,最终执行又是另外一个线程。前者是生产者,后者是消费者,这种模式隔离了“做什么”和“怎么做”,实现了业务上的解耦。

其具体实现方式是线程A调用了对象O的wait()方法进入等待状态,另一个线程B调用对象B的notify() or notifyAll()方法,线程A收到通知后从对象O的wait()方法返回,进而执行后续操作 。其逻辑流程如下:

thread1 得到object1 的 monitor, 调用 object1.wait()   - 释放object1 的 monitor, thread1 wait;thread2 得到 object1 的 monitor, 调用 object1.notify()   - 激活thread1, 释放object1 的 monitor;thread1 得到 object1 的 monitor, 从object1.wait()返回, thread1接着执行.
演示demo如下:

import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.TimeUnit;public class WaitNotify {    static boolean flag = true;    static Object lock = new Object();    public static void main(String[] args) throws Exception {        Thread waitThread = new Thread(new Wait(), "WaitThread");        waitThread.start();        TimeUnit.SECONDS.sleep(1);        Thread notifyThread = new Thread(new Notify(), "NotifyThread");        notifyThread.start();    }    static class Wait implements Runnable {        @Override        public void run() {            synchronized (lock) {                while (flag) {                    try {                        System.out.println(Thread.currentThread() + " flag is true. wait @ "                                + new SimpleDateFormat("HH:mm:ss").format(new Date()));                        lock.wait();                    } catch (InterruptedException e) {                    }                }                System.out.println(Thread.currentThread() + " flag is false. running @ "                        + new SimpleDateFormat("HH:mm:ss").format(new Date()));            }        }    }    static class Notify implements Runnable {        @Override        public void run() {            synchronized (lock) {                System.out.println(Thread.currentThread() + " hold lock. notify @ "                        + new SimpleDateFormat("HH:mm:ss").format(new Date()));                lock.notifyAll();                flag = false;                SleepUtils.second(5);            }            synchronized (lock) {                System.out.println(Thread.currentThread() + " hold lock again. sleep @ "                        + new SimpleDateFormat("HH:mm:ss").format(new Date()));                SleepUtils.second(5);            }        }    }}


原创粉丝点击