文档章节

Java wait && notify

秋风醉了
 秋风醉了
发布于 2014/11/18 11:11
字数 972
阅读 620
收藏 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==============

© 著作权归作者所有

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

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

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

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

milne
2015/08/18
0
0
java并发编程(2)——wait和notify解析

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

十二缸帕萨特
2014/04/12
0
0
Java Thread及其synchronized,wait,sleep,join,yeid,interrupt

Java SE7 API - Thread: http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield%28%29 参考资料:http://blog.csdn.net/lqqmisslll/article/details/54208491 一、线程的简......

YuanyuanL
2015/08/12
0
0
Core Java基础知识之一(线程私房菜)

Java的高明之处就是在于不断的总结实际应用中不断出现的通用问题,为此提供此类问题的底层实现,向调用者提供解决问题的接口实现,调用者大可不必完全的明白底层的实现原理和实现过程,只要照...

保罗的寓言
2011/05/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

php获取客户端IP

php获取客户端IP 首先先阅读关于IP真实性安全的文章:如何正確的取得使用者 IP? 「任何從客戶端取得的資料都是不可信任的!」 HTTP_CLIENT_IP头是有的,但未成标准,不一定服务器都实现。 ...

DrChenXX
11分钟前
0
0
. The valid characters are defined in RFC 7230 and RFC 问题

通过这里的回答,我们可以知道: Tomcat在 7.0.73, 8.0.39, 8.5.7 版本后,添加了对于http头的验证。 具体来说,就是添加了些规则去限制HTTP头的规范性 参考这里 具体来说: org.apache.tom...

west_coast
29分钟前
1
0
刷leetcode第704题-二分查找

今天双十一买的算法书到货了,路上刷到有人说的这个题,借(chao)鉴(xi)一下别人的思路,这个是C++标准库里面的经典方法,思路精巧,优雅好品味 int search(int* nums, int numsSize, in...

锟斤拷烫烫烫
55分钟前
1
0
【分享实录】BANCOR算法详解及代码实现

1 活动基本信息 1)主题:【区块链技术工坊22期】BANCOR算法详解及代码实现 2)议题: BANCOR算法的特点和优劣势 BANCOR算法和举例 如何加入BANCOR.NETWORK交易所 如何开发自己的BANCOR去中心...

HiBlock
今天
2
0
微信小程序(2)

开始看微信小程序的教程了。刚刚看完官方教程的视图层部分。这里摘录一些自己认为的部分关键点。 1.直接修改数值无法重新渲染,需要使用setData()方法; 2.列表渲染中:wx:key用于保持项目在...

MKjy
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部