`
talentluke
  • 浏览: 600841 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

notify()和notifyAll()

 
阅读更多

 

关于方法notify()和notifyAll()哪些说法是正确的?? 
请选出两个正确答案 
A)类Thread的一个实例有一个名为notify()的方法,该方法可以被调用。 
B)一个到方法notify()的调用将唤醒当前拥有对象锁定的线程。 
C)方法notify()是同步的。 
D)方法notifyAll()在类Thread中被定义的。 
E)当有超过一个线程在等待获得一个对象的锁定时,那么就无法确定notify()方法将通知哪个线程。      

A是对的,因为万物皆是类,Thread对象也是Object对象,所以也拥有notify方法,这种说法看似乎很怪,想想线程本身拥有这两个方法,未必有用,但在线程池中,线程做为一个对象进行存取控制的时候,就有用了。

B是错的。B的不是特别严谨,notify唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。另外还一个严重的说法错误,如果现有线程不是对象锁定的主人,那么将抛出一个IllegalMonitorStateException错误。

C是错的。notify方法在Object类中定义,但调用notify必须在同步代码块中调用。此方法不同步,但是如果现有线程不是对象锁定的主人,那么将抛出一个IllegalMonitorStateException,这两者理解上千万不要混淆在一起。在API中,方法的原型说明:     

public final void notify()
唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。

D是错的。明显是错的。

E是对的。对象在wait时会释放synchonrized的锁,被唤醒后会重新获取。notify() 是随机选择其中一个唤醒,其它仍然在wait。notifyAll() 是全部都唤醒,全部都尝试重获锁,当然只有其中一个会得到并继续执行,其它得不到锁的继续等待,但这时是等待锁而不是等待notify

 

 

notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。两者的最大区别在于:

notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,它们就会去竞争。notify则文明得多他只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们,当第一个线程运行完毕以后释放对象上的锁此时如果该对象没有再次使用notify语句,则即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这个对象发出一个notify或notifyAll,它们等待的是被notify或notifyAll,而不是锁

import java.util.*;
class Widget{}
class WidgetMaker extends Thread{
    List finishedWidgets=new ArrayList();
    public void run(){
        try{
            while(true){
                Thread.sleep(5000);//act busy
                Widget w=new Widget();
                //也就是说需要5秒钟才能新产生一个Widget,这决定了一定要用notify而不是notifyAll
                //因为上面两行代码不是同步的,如果用notifyAll则所有线程都企图冲出wait状态
                //第一个线程得到了锁,并取走了Widget(这个过程的时间小于5秒,新的Widget还没有生成)
                //并且解开了锁,然后第二个线程获得锁(因为用了notifyAll其他线程不再等待notify语句
                //,而是等待finishedWidgets上的锁,一旦锁放开了,他们就会竞争运行),运行
                //finishedWidgets.remove(0),但是由于finishedWidgets现在还是空的,
                //于是产生异常
                //***********这就是为什么下面的那一句不能用notifyAll而是要用notify
 
                synchronized(finishedWidgets){
                    finishedWidgets.add(w);
                    finishedWidgets.notify(); //这里只能是notify而不能是notifyAll
                }
            }
        }
        catch(InterruptedException e){}
    }
 
    public Widget waitForWidget(){
        synchronized(finishedWidgets){
            if(finishedWidgets.size()==0){
                try{
                    finishedWidgets.wait();
                }
                catch(InterruptedException e)
                {}
            }
            return finishedWidgets.remove(0);
        }
    }
}
public class WidgetUser extends Thread{
    private WidgetMaker maker;
    public WidgetUser(String name,WidgetMaker maker){
        super(name);
        this.maker=maker;
    }
    public void run(){
        Widget w=maker.waitForWidget();
        System.out.println(getName()+"got a widget");
    }
 
    public static void main(String[] args) {
        WidgetMaker maker=new WidgetMaker();
        maker.start();
        new WidgetUser("Lenny",maker).start();
        new WidgetUser("Moe",maker).start();
        new WidgetUser("Curly",maker).start();
    }
}
分享到:
评论

相关推荐

    如何在Java中正确使用 wait, notify 和 notifyAll

    wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视。本文对这些关键字的使用进行了描述。  在 Java 中可以用 wait、notify 和 notifyAll 来实现...

    Java 同步方式 wait和notify/notifyall

    在Java中,`wait()`, `notify()`, 和 `notifyAll()` 是Java Object类的三个方法,它们在实现线程间通信和协作时扮演着关键角色。这些方法主要用于解决线程等待和唤醒的问题,是基于Java Monitor(监视器)模型的。 ...

    Java notify和notifyAll的区别和相同

    Java中的`notify`和`notifyAll`是多线程编程中的关键方法,它们用于线程间的通信,特别是在处理同步机制时。这两个方法都是在`Object`类中定义的,因此可以应用于任何Java对象。 首先,我们需要理解Java的同步机制...

    java notify和notifyAll的对比

    Java中的`notify`和`notifyAll`方法是多线程编程中的重要概念,它们都是`Object`类的方法,用于在同步控制中唤醒等待在特定对象监视器上的线程。理解这两个方法的区别对于编写高效的并发代码至关重要。 首先,`...

    Java多线程中wait、notify、notifyAll使用详解

    6. notify 和 notifyAll的区别notify方法只唤醒一个等待(对象的)线程并使该线程开始执行,而notifyAll 会唤醒所有等待(对象的)线程。 五、wait、notify、notifyAll方法的使用场景 wait、notify、notifyAll方法...

    基于Java多线程notify与notifyall的区别分析

    Java中的多线程编程是构建高效并发应用的关键技术之一,其中`wait()`、`notify()`和`notifyAll()`是Java对象锁机制中的三个关键方法,它们位于`java.lang.Object`类中,主要用于线程间通信。本文将深入探讨`notify()...

    wait,notify等线程知识.pdf

    Java中的多线程协同工作是通过一系列的同步机制来实现的,其中wait、notify和notifyAll是基于对象监视器的同步原语。这些方法在Java的Object类中定义,主要用于线程间的通信和协作,确保资源的安全访问。下面将详细...

    【并发编程】 — 线程间的通信wait、notify、notifyAll

    文章目录1 wait、notify、notifyAll简单介绍1.1 使用方法 + 为什么不是Thread类的方法1.2 什么时候加锁、什么时候释放锁?1.3 notify、notifyAll的区别2 两个比较经典的使用案例2.1 案例1 — ABCABC。。。三个线程...

    Java多线程与并发系列22道高频面试题(附思维导图和答案解析)

    本文总结了Java多线程与并发系列的22道高频面试题,涵盖了多线程的实现方法、线程停止、notify和notifyAll的区别、sleep和wait的区别、volatile关键字的作用等多方面的知识点。 一、Java中实现多线程的方法 Java中...

    源码—Java多线程5—死锁和wait notify notifyAll

    源码—Java多线程5—死锁和wait notify notifyAll

    java多线程.pdf

    Java提供了多种同步机制来控制多个线程对共享资源的互斥访问,包括synchronized关键字和Object类中的wait、notify和notifyAll方法。synchronized关键字可以用来修饰方法或者代码块,确保同一时刻只有一个线程可以...

    多线程同步和通讯完整示例

    - 使用wait、notify和notifyAll时,应避免死锁和活锁。 ### 三、Lock接口 Java 5引入了java.util.concurrent.locks包,其中的Lock接口提供了比synchronized更细粒度的锁控制。Lock接口提供了一些额外的功能,如可...

    java中的并发和多线程编程中文版

    读者将通过使用java.lang.thread类、synchronized和volatile关键字,以及wait、notify和notifyall方法,学习如何初始化、控制和协调并发操作。此外,本书还提供了有关并发编程的全方位的详细内容,例如限制和同步、...

    Java并发编程:设计原则与模式(第二版)

    读者将通过使用java.lang.thread类、synchronized和volatile关键字,以及wait、notify和notifyall方法,学习如何初始化、控制和协调并发操作。此外,本书还提供了有关并发编程的全方位的详细内容,例如限制和同步、...

    wait()、notify()和notifyAll()方法2---马克-to-win java视频

    wait()、notify()和notifyAll()方法2---马克-to-win java视频

    wait()、notify()和notifyAll()方法1---马克-to-win java视频

    wait()、notify()和notifyAll()方法1---马克-to-win java视频

    基于Java多线程与线程安全实践(源码+使用文档)

    线程通信:展示线程间的通信机制,包括wait、notify和notifyAll的使用。 线程池管理:提供线程池的使用示例,展示如何有效管理线程资源。 原子变量操作:展示如何使用AtomicInteger等原子类进行线程安全的变量操作。...

    Java 30道面试题和答案.docx

    11. **线程同步**:Java提供synchronized、wait、notify和notifyAll等机制来控制线程并发。wait使线程进入等待状态,notify和notifyAll唤醒等待的线程。 12. **线程与进程**:进程是系统资源分配的基本单位,线程是...

    Java多线程基础 线程的等待与唤醒(wait、notify、notifyAll)

    Java多线程基础中的线程等待与唤醒是一种常见的线程协作机制,通过wait()、notify()和notifyAll()方法来实现线程之间的同步和通信。在本节中,我们将详细介绍wait()、notify()和notifyAll()方法的使用和实现原理。 ...

    Java多线程同步(wait()notify()notifyAll())[文].pdf

    本文将深入探讨Java中的wait()、notify()和notifyAll()方法,以及synchronized关键字和原子操作在多线程环境中的应用。 1. **wait()方法**: - wait()是Object类的一个方法,它的作用是让当前线程暂停执行并释放它...

Global site tag (gtag.js) - Google Analytics