文档章节

Java wait && notify

秋风醉了
 秋风醉了
发布于 2014/11/18 11:11
字数 972
阅读 623
收藏 4

Java wait && notify

wait、notify和notifyAll方法是Object类的final native方法,所以这些方法不能被子类重写。

方法 notifyAll()

Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the{wait} methods.

该方法只能在同步方法或同步块内部调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。

 

方法 notify()

Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the {wait} methods.

该方法只能在同步方法或同步块内部调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。

 

方法 wait()

Causes the current thread to wait until another thread invokes the {java.lang.Object#notify()} method or the {java.lang.Object#notifyAll()} method for this object.The current thread must own this object's monitor. 

调用该方法的线程进入WAITING 状态,只有等待另外线程的通知或被中断才会返回,需要注意的是调用wait方法后,才会释放对象的锁。

该方法只能在同步方法中调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。下面是一个wait的示例

synchronized (object) {
   while (<condition does not hold>)
      object.wait();
      // ... 
}

 

方法 wait(long millis)&&wait(long millis,int nanos)

Causes the current thread to wait until another thread invokes the { java.lang.Object#notify()} method or the {java.lang.Object#notifyAll()} method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed(消逝,过去).

超时等待一段时间后,这里的参数时间是毫秒,也就是等待长达n毫秒,如果没有通知就超时返回。

这些方法只能在同步方法中调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。

timeout -- 最大的等待时间(以毫秒为单位)。

nanos   -- 额外的时间,在纳秒范围为0-999999。

‍Object.wait()和Object.notify()和Object.notifyAll()必须写在synchronized方法内部或者synchronized块内部,这是因为:这几个方法要求当前正在运行object.wait()方法的线程拥有object的对象锁(内置锁)。即使你确实知道当前上下文线程确实拥有了对象锁,也不能将object.wait()这样的语句写在当前上下文中。‍

 

下面这段代码的写法是错误的。

package sync;

class A {
    public synchronized void printThreadInfo() throws InterruptedException {
        Thread t = Thread.currentThread();
        System.out.println("ThreadID:" + t.getId() + ", ThreadName:" + t.getName());
    }
}


public class ObjectWaitTest {
    public static void main(String args[]) {
        A a = new A();
        //因为printThreadInfo()方法抛出InterruptedException异常,所以这里必须使用try-catch块
        try {
            a.printThreadInfo();
            a.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

应该要这么写:

package sync;

class A {
    public synchronized void printThreadInfo() throws InterruptedException {
        Thread t = Thread.currentThread();
        System.out.println("ThreadID:" + t.getId() + ", ThreadName:" + t.getName());
        // this.wait();//一直等待
        this.wait(1000);//等待1000ms
        // super.wait(1000);
    }
}


public class ObjectWaitTest {
    public static void main(String args[]) {
        A a = new A();
        //因为printThreadInfo()方法抛出InterruptedException异常,所以这里必须使用try-catch块
        try {
            a.printThreadInfo();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Thread t = Thread.currentThread();
        System.out.println("ThreadID:" + t.getId() + ", ThreadName:" + t.getName());
    }
}

完整示例,

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class WaitNotifyDemo {


    static boolean flag = true;

    static Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {

        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() {
            // 加锁 拥有lock 的 monitor
            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) {
                        e.printStackTrace();
                    }
                }

                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;

                try {
                    Thread.sleep(1000 * 5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

以上就是关于wait和notify方法的用法。

参考:http://www.cnblogs.com/xwdreamer/archive/2012/05/12/2496843.html

后记:Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。

==============END==============

© 著作权归作者所有

共有 人打赏支持
秋风醉了
粉丝 241
博文 566
码字总数 417505
作品 0
朝阳
程序员
私信 提问
Java多线程学习(四)等待/通知(wait/notify)机制

系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Ja...

一只蜗牛呀
2018/04/16
0
0
wait、notify、notifyAll

wait()、notify()、notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态。 这三个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。 如果对象调用...

milne
2015/08/18
0
0
多线程通信的三大法器,你真的会用吗?

wait, notify, notifyAll 是多线程之间通信最重要的 3 个方法,今天,栈长给大家普及一下它们的知识要点及应用实战。 定义 wait:让持有该对象锁的线程等待; notify: 唤醒任何一个持有该对象...

Java技术栈
2018/11/27
0
0
基于 JVMTI 实现 Java 线程的监控

随着多核 CPU 的日益普及,越来越多的 Java 应用程序使用多线程并行计算来充分发挥整个系统的性能。多线程的使用也给应用程序开发人员带来了巨大的挑战,不正确地使用多线程可能造成线程死锁...

红薯
2009/12/15
1K
1
java并发编程(2)——wait和notify解析

JAVA的进程同步是通过synchronized()来实现的,需要说明的是,JAVA的synchronized()方法类似于操作系统概念中的互斥内存块,在JAVA中的Object类型中,都是带有一个内存锁的,在有线程获取该内...

十二缸帕萨特
2014/04/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

mosquitto 集群搭建

在Mosquitto集群中,客户端可以在任何节点上订阅主题,也可以在任何节点上发布消息,集群会保证消息按需转发到正确的节点。 为了均衡负载及避免单点故障,Mosquitto集群实现为完全去中心化、...

yanlijun_java
24分钟前
5
0
阿里高级技术专家:研发效能的追求永无止境

背景 大约在5年前,也就是2013年我刚加入阿里的时候,那个时候 DevOps 的风刚吹起来没多久,有家公司宣称能够一天发布几十上百次,这意味着相比传统软件公司几周一次的发布来说,他们响应商业...

阿里云云栖社区
28分钟前
1
0
正则匹配demo

要求:密码中有大写字母,小写字母,以及数字 package com.example.demo;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * @author seif * @Description: ...

经常把天聊死的胖子
28分钟前
5
0
阿里重磅开源首款自研科学计算引擎Mars,揭秘超大规模科学计算

日前,阿里巴巴正式对外发布了分布式科学计算引擎 Mars 的开源代码地址,开发者们可以在pypi上自主下载安装,或在Github上获取源代码并参与开发。 此前,早在2018年9月的杭州云栖大会上,阿里...

阿里云官方博客
29分钟前
3
0
在 Kubernetes 中配置私有 DNS 和上游域名服务器

Before you begin You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a clust......

xiaomin0322
38分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部