zoukankan      html  css  js  c++  java
  • java线程的等待、通知机制【读书笔记】

    代码示例:

    package com.baidu.nuomi.concurrent;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.TimeUnit;
    
    /**
     * Created by sonofelice on 16/6/18.
     */
    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);
                }
            }
        }
    }

    输出如下:

    Thread[WaitThread,5,main] flag is true. wait @ 12:21:04
    Thread[NotifyThread,5,main]hold lock. notify @ 12:21:05
    Thread[NotifyThread,5,main]hold lock again. sleep @ 12:21:10
    Thread[WaitThread,5,main]flag is false. running @ 12:21:15
    
    Process finished with exit code 0

    调用wait() notify()  notifyAll()方法时需要注意的细节:

    1)使用wait() notify()  notifyAll() 时需要先对调用对象加锁;

    2)调用wait()方法后,线程状态由RUNNING 变为WAITING,并将当前线程放置到对象的等待队列。

    3)notify()或notifyAll() 方法调用后,等待线程依旧不会从wait返回,需要调用notify()或notifyAll()的线程释放锁之后,等待线程才有机会从wait()返回。

    4)notify()方法将等待队列中的一个等待线程从等待队列中移到同步队列中,而notifyAll()方法则是将等待队列中的所有的线程全部移到同步队列,被移动的线程状态由WAITING变为BLOCKED。

    5)从wait()方法返回的前提是获得了调用对象的锁。

    从上面的细节可以看出,等待/通知机制依托于同步机制,其目的就是确保等待线程从wait()方法返回时能够感知到通知线程对变量做出的修改。

    从而抽象出等待/通知的经典范式:

    等待方:

    1)获取对象锁;

    2)如果条件不满足,那么调用对象的wait()方法,被通知后仍要检查条件。

    3)条件满足则执行对应的逻辑。

    对应的伪代码如下:

    synchronized(对象){

    while(条件不满足){

     Object.wait();

    }

    逻辑处理

    }

    通知方:

    1)获得对象的锁;

    2)改变条件;

    3)通知所有等待在对象上的线程。

    对应的伪代码如下:

    synchronized(对象){

      改变条件

      对象.notifyAll();

    }

  • 相关阅读:
    如何修改配置文件:CentOS下SSH端口修改
    linux ssh_config和sshd_config配置文件学习
    linux文件权限命令chmod学习
    硬盘接口类型介绍
    Linux中权限(r、w、x)对于目录与文件的意义
    谈谈对虚拟DOM的理解
    对于深入响应式原理的深刻理解
    环套树 or 基环树 找环
    POI 2014 little bird
    洛谷P2876 [USACO07JAN]解决问题Problem Solving
  • 原文地址:https://www.cnblogs.com/sonofelice/p/5596159.html
Copyright © 2011-2022 走看看