`
hz_chenwenbiao
  • 浏览: 1008036 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

一个理解wait()与notify()的例子(转)

阅读更多

下面是我原来在CSDN论坛上看到的一个贴子,涉及到同步,wait(),notify()等概念的理解,我试着根据原来的一些回复和Think in Java上的相关概念将wait()和notify()这两个方法剖析了一下,欢迎指教.

问题如下:

分析这段程序,并解释一下,着重讲讲synchronized、wait(),notify 谢谢!

class ThreadA 
{
  public static void main(String[] args) 
  {
    ThreadB b=new ThreadB();
    b.start();
    System.out.println("b is start....");
    synchronized(b)//括号里的b是什么意思,起什么作用?
    {
      try
      {
 System.out.println("Waiting for b to complete...");
 b.wait();//这一句是什么意思,究竟让谁wait?
        System.out.println("Completed.Now back to main thread");
      }catch (InterruptedException e){}
    }
    System.out.println("Total is :"+b.total);
   }
}
 
class ThreadB extends Thread
{
  int total;
  public void run()
  {
    synchronized(this)
    {
      System.out.println("ThreadB is running..");
      for (int i=0;i<100;i++ )
      {
        total +=i;
        System.out.println("total is "+total);
      }
      notify();
    }
  }
}

 要分析这个程序,首先要理解notify()和wait(),为什么在前几天纪录线程的时候没有纪录这两个方法呢,因为这两个方法本来就不属于Thread类,而是属于最底层的object基础类的,也就是说不光是Thread,每个对象都有notify和wait的功能,为什么?因为他们是用来操纵锁的,而每个对象都有锁,锁是每个对象的基础,既然锁是基础的,那么操纵锁的方法当然也是最基础了.

 

 再往下看之前呢,首先最好复习一下Think in Java的14.3.1中第3部分内容:等待和通知,也就是wait()和notify了.

按照Think in Java中的解释:"wait()允许我们将线程置入“睡眠”状态,同时又“积极”地等待条件发生改变.而且只有在一个notify()或notifyAll()发生变化的时候,线程才会被唤醒,并检查条件是否有变."

  我们来解释一下这句话.


  "wait()允许我们将线程置入“睡眠”状态",也就是说,wait也是让当前线程阻塞的,这一点和sleep或者suspend是相同的.那和sleep,suspend有什么区别呢?

 

   区别在于"(wait)同时又“积极”地等待条件发生改变",这一点很关键,sleep和suspend无法做到.因为我们有时候需要通过同步(synchronized)的帮助来防止线程之间的冲突,而一旦使用同步,就要锁定对象,也就是获取对象锁,其它要使用该对象锁的线程都只能排队等着,等到同步方法或者同步块里的程序全部运行完才有机会.在同步方法和同步块中,无论sleep()还是suspend()都不可能自己被调用的时候解除锁定,他们都霸占着正在使用的对象锁不放.


   而wait却可以,它可以让同步方法或者同步块暂时放弃对象锁,而将它暂时让给其它需要对象锁的人(这里应该是程序块,或线程)用,这意味着可在执行wait()期间调用线程对象中的其他同步方法!在其它情况下(sleep啊,suspend啊),这是不可能的.


   但是注意我前面说的,只是暂时放弃对象锁,暂时给其它线程使用,我wait所在的线程还是要把这个对象锁收回来的呀.wait什么?就是wait别人用完了还给我啊!


   好,那怎么把对象锁收回来呢?


   第一种方法,限定借出去的时间.在wait()中设置参数,比如wait(1000),以毫秒为单位,就表明我只借出去1秒中,一秒钟之后,我自动收回.


   第二种方法,让借出去的人通知我,他用完了,要还给我了.这时,我马上就收回来.哎,假如我设了1小时之后收回,别人只用了半小时就完了,那怎么办呢?靠!当然用完了就收回了,还管我设的是多长时间啊.

 

   那么别人怎么通知我呢?相信大家都可以想到了,notify(),这就是最后一句话"而且只有在一个notify()或notifyAll()发生变化的时候,线程才会被唤醒"的意思了.


   因此,我们可将一个wait()和notify()置入任何同步方法或同步块内部,无论在那个类里是否准备进行涉及线程的处理。而且实际上,我们也只能在同步方法或者同步块里面调用wait()和notify().

 

   这个时候我们来解释上面的程序,简直是易如反掌了.

 

   synchronized(b){...};的意思是定义一个同步块,使用b作为资源锁。b.wait();的意思是临时释放锁,并阻塞当前线程(即这里的主线程,调用b的线程,就像说我想休息一下,让给占有b锁的人执行),好让其他使用同一把锁的线程有机会执行,在这里要用同一把锁的就是b线程本身.这个线程在执行到一定地方后用notify()通知wait的线程,锁已经用完,待notify()所在的同步块运行完之后,wait所在的线程就可以继续执行.

分享到:
评论

相关推荐

    一个理解wait()与notify()的例子

    ### 一个理解wait()与notify()的例子 #### 知识点概述 本文旨在解析一个具体的Java多线程示例代码,以帮助读者更好地理解`wait()`与`notify()`方法的作用及其实现机制。这两个方法是Java中实现线程间通信的重要...

    Java 同步方式 wait和notify/notifyall

    下面是一个简单的生产者消费者模型示例,演示了`wait()`, `notify()` 的使用: ```java public class Buffer { private int data; private boolean available = false; public synchronized void put(int item)...

    wait_notify_demo

    1. `wait()`: 当一个线程调用某个对象的`wait()`方法时,它会释放该对象的锁,并进入等待状态,直到其他线程调用了该对象的`notify()`或`notifyAll()`方法唤醒它。等待的线程不会自动恢复执行,而是需要重新竞争对象...

    Java多线程wait和notify

    下面是一个简单的例子,展示了如何通过 `wait()` 和 `notify()` 控制子线程的执行: ```java public class ThreadControl { private boolean running = false; private Object monitor = new Object(); public ...

    java中几个notify、wait使用实例

    接下来,我们通过几个具体的例子来理解这些方法的使用: #### 示例一:线程交替打印数字 在第一个示例中,我们有两个线程`Thread1`和`Thread2`,它们分别打印1-10和11-20之间的数字,但是必须交替进行。为了实现这...

    等待机制与锁机制wait notify

    本文将深入探讨`wait`、`notify`以及`notifyAll`这三个关键字的使用及其背后的原理,帮助你理解如何在实际编程中有效地利用它们来解决线程同步问题。 首先,我们需要了解Java中的对象锁。每个Java对象都有一个内置...

    java-wait和notify的用法.pdf

    在Java编程语言中,`wait()`和`notify()`是Object类中的两个关键方法,它们用于线程间的协作和通信。这两个方法在多线程环境下尤其重要,因为它们允许线程等待特定条件并通知其他线程继续执行。在分析给定的程序之前...

    一家三口共用同一账户银行卡,wait();notify();

    在给定的代码示例中,我们看到了一个模拟家庭共享同一银行账户的场景,通过使用Java多线程的wait()和notify()方法来控制不同线程(代表家庭成员)的操作顺序。这里涉及到的关键知识点包括: 1. **Java多线程**:...

    Monitor.wait例子.rar

    在Java编程语言中,`Monitor`是一个重要的概念,它与多线程同步密切相关。`Monitor`通常是由一个或多个对象锁(synchronized关键字)保护的区域,确保在任何时刻只有一个线程可以访问这部分代码。`wait()`和`pulse()...

    详细分析java线程wait和notify

    `notify()`方法则会随机唤醒一个因调用该对象`wait()`方法而等待的线程,而`notifyAll()`会唤醒所有等待的线程。 在使用`wait()`和`notify()`时,必须确保它们在`synchronized`上下文中调用,这通常是在`...

    java代码-wait-notify 生产者消费者

    1. `wait()`: 当一个线程调用对象的`wait()`方法时,它会释放该对象的锁并进入等待状态,直到其他线程调用该对象的`notify()`或`notifyAll()`方法唤醒它。在等待期间,该线程不会消耗CPU资源。 2. `notify()`: 这个...

    一个简单的线程例子

    在这个简单的线程例子中,我们将深入理解线程的概念、如何创建和管理线程,以及它们在多任务处理中的作用。 线程是操作系统分配CPU时间片的基本单位,它们共享同一进程的资源,如内存空间和文件句柄,但拥有独立的...

    08 集体协作,什么最重要?沟通!—线程的等待和通知.pdf

    本文将深入探讨这一主题,基于Java并发编程学习宝典(漫画版)的内容,我们将理解wait和notify的概念,同步的重要性,以及如何正确使用它们。 1. wait/notify 概念 wait()和notify()是Java并发编程中非常重要的两个...

    java多线程设计wait[参考].pdf

    在使用wait/notify机制时,推荐优先使用`notifyAll()`,因为它能保证至少有一个线程可以继续执行,避免死锁和饥饿的情况。同时,为了避免无休止的等待,通常在调用`wait()`之前会使用一个`while`循环检查条件是否...

    Java线程同步例子.pdf

    在Java编程中,线程同步是一种重要的多线程控制机制,用于解决多个线程访问共享资源时可能出现...通过这个例子,我们可以理解Java如何利用同步机制实现多线程环境下的安全通信和协作,这对于开发并发应用程序至关重要。

    java经典10个例子

    "Java经典10个例子"通常会涵盖Java语言的核心概念和常用功能,旨在帮助初学者理解并掌握Java编程的关键点。以下是对这十个经典例子可能涉及的知识点的详细解释: 1. ** HelloWorld **:这是每个学习编程语言的人...

    Java开发宝典的所有例子

    5. **多线程**:Java支持多线程编程,例子会介绍Thread类的使用、线程同步方法(如synchronized关键字、wait()、notify()等)以及并发工具类如Semaphore、CountDownLatch等。 6. **网络编程**:Java的Socket编程...

    100个Java经典例子后端- Java

    6. **多线程**: 理解线程的创建(Thread类和Runnable接口)、线程同步(synchronized关键字、wait()、notify()、锁对象等)以及并发工具类(如ExecutorService、Future、Callable)。 7. **数据库操作**: JDBC...

    Java教程例子 教程 例子

    例子可能涵盖了如何创建和启动线程,线程同步(如`synchronized`关键字、`wait()`, `notify()`方法)以及线程池的使用。 以上只是部分可能涵盖的Java知识点,实际例子中可能还涉及了更多的主题,如反射、注解、枚举...

    JAVA代码大全的例子

    在"代码大全的例子"中,你可能会看到如何创建和管理线程,以及如何使用同步机制(如synchronized关键字、wait()、notify()和notifyAll()方法)来避免线程竞态条件。 最后,Java还提供了丰富的标准库,如Swing和...

Global site tag (gtag.js) - Google Analytics