`
san_yun
  • 浏览: 2652221 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

Thread之wait()&notify()

    博客分类:
  • java
阅读更多
问题:假想在服务器上运行着若干个响应客户端请求的线程,这些线程需要连接到同一数据库,但任一时刻只能获得一定数目的数据库连接。你要怎样才能够将这些固定数量的数据库连接分配给大量的线程?

一种控制访问特定资源的方法,就是使用信号量计数. 我们可以将一个信号量初始化为可获得的数据库连接个数。一旦某个线程获得了信号量,可获得的数据库连接数减一。线程消耗完资源并释放该资源时,计数器就会加一。当信号量控制的所有资源都已被占用时,若有线程试图访问此信号量,则会进入阻塞状态,直到有可用资源被释放.

信号量最常见的用法是解决“消费者-生产者问题”。当一个线程进行工作时,若另外一个线程访问同一共享变量,就可能产生此问题。消费者线程只能在生产者线程完成生产后才能够访问数据。使用信号量来解决这个问题,就需要创建一个初始化为零的信号量,从而让消费者线程访问此信号量时发生阻塞。每当完成单位工作时,生产者线程就会向该信号量发信号(释放资源)。每当消费者线程消费了单位生产结果并需要新的数据单元时,它就会试图再次获取信号量。因此信号量的值就总是等于生产完毕可供消费的数据单元数。这种方法比采用消费者线程不停检查是否有可用数据单元的方法要高效得多。因为消费者线程醒来后,倘若没有找到可用的数据单元,就会再度进入睡眠状态,这样的操作系统开销是非常昂贵的。

举一个简单的例子:
假设有两个线程,彼此需要通信。再假设线程A正在等线程B的消息:
// Thread A
public void waitForMessage() {
    while (hasMessage == false) {
        Thread.sleep(100);
    }
}
// Thread B
public void setMessage(String message) {
    ...
    hasMessage = true;
}



这样写可以,但比较糟糕。线程A需要每100ms检测一次(一秒检测10次)线程B是否发送了消息;它也可能睡过了头(指Thread.sleep(100)——译者),没能及时接收消息。还有,如果多个线程都在等待消息,应该怎么办?难道没有一种方式可以让线程A不用这么呆头呆脑的等线程B的消息吗?
幸运的是,wait() 和 notify()方法能做到。
Wait()方法用在同步的代码块里,当wait()被执行时,锁会被释放,线程进入等待状态。
方法notify() 同样用在同步的代码块里。Notify()将通知等待相同锁的线程,如果有多个线程在等待这个锁,将从中随机选择一个进行通知。

下面是更新的代码:
// Thread A
public synchronized void waitForMessage() {
    try {
        wait();
    }
    catch (InterruptedException ex) { }
}

// Thread B
public synchronized void setMessage(String message) {
    ...
    notify();
}

线程B调用notify(),并离开这个同步方法后(释放加在this上的锁), 线程A 重新获得这个锁,并完成它的同步代码。本例中,它只是返回。
你也可以选择等待的最大时间值,wait()方法可以将其作为参数:
wait(100);
如果线程从未被通知,这种写法等价于让线程sleep一个指定时间;不幸的是,我们没法知道wait()方法的返回是由于等待的时间到了,还是由于线程被通知。
另一种通知的方法, notifyAll(), 将会通知所有等待这个锁的线程,而不是只通知一个。
方法 wait(), notify(), 和 notifyAll() 是Object 类的方法,因此所有的Java对象都会有这些方法,就像所有的Java对象都可用作一个锁一样。
分享到:
评论

相关推荐

    Java多线程wait和notify

    在Java中,`wait()` 和 `notify()` 方法是实现线程间通信和协作的重要工具,它们属于 `java.lang.Object` 类,这意味着所有类都默认继承了这两个方法。本文将详细探讨如何使用 `wait()` 和 `notify()` 来控制子线程...

    深入理解Wait、Notify和Wait与sleep区别

    本文将深入探讨`wait()`, `notify()`以及它们与`sleep()`方法的区别,这些都是Java中与线程同步密切相关的概念。 首先,`wait()`, `notify()`和`notifyAll()`是Object类中的方法,它们主要用于线程间通信和协作。...

    java中几个notify、wait使用实例

    在Java的多线程编程中,`notify()`与`wait()`是实现线程间通信的重要方法,它们主要用于解决生产者消费者问题、读者写者问题等典型同步问题。这两个方法定义在`Object`类中,因此所有Java对象都可以作为锁来使用。在...

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

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

    wait,notify等线程知识.pdf

    ### wait, notify等线程知识详解 #### 一、引言 在计算机程序设计中,尤其是在多线程环境中,线程间的同步与通信是保证程序正确性和效率的关键因素之一。`wait` 和 `notify` 是Java语言提供的原生方法,用于解决...

    Object类wait及notify方法原理实例解析

    Object类中的wait和notify方法是Java多线程编程中最重要的同步机制之一,它们是Java.lang.Object类中的两个方法,用于在多线程之间进行通信和同步。wait方法将当前线程置于等待状态,而notify方法则用于唤醒等待的...

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

    *练习wait()和notify()方法 */ public class TestBank {  public static void main(String[] args) {  Account acc = new Account(“1234” , “1234” , 2000.0);  Thread h = new Thread(new Husband(acc) , ...

    java-wait和notify的用法.pdf

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

    等待机制与锁机制wait notify

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

    详解Java程序并发的Wait-Notify机制

    在Java中,`wait()`, `notify()`, `notifyAll()`方法是`Object`类的成员,而不是`Thread`类的,这意味着任何对象都可以作为等待和通知的基础。 **1. 状态变量(State Variable)** 状态变量是线程间通信的关键。当...

    Java 中Object的wait() notify() notifyAll()方法使用

    在并发编程中,除了Thread外,对Object对象的wait()和notify()方法也应该深入了解其用法,虽然知识点不多,但非常重要。wait()、notify()和notifyAll()方法都是Object类的方法,可以认为任意一个Object都是一种资源...

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

    5. **中断处理**:线程在等待时可能需要响应中断,`Thread.interrupt()`方法可以用来中断线程,而`wait()`方法会抛出`InterruptedException`,允许程序优雅地处理中断。 6. **哲学家就餐问题**:这是一个经典的多...

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

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

    wait()编程wait()编程wait()编程wait()编程

    - `wait()`是可中断的,当线程被中断(`Thread.interrupt()`)时,`wait()`会抛出`InterruptedException`,这时线程需要处理中断状态,决定是否继续等待或结束。 - 使用`wait()`时,应避免无限期等待,通常建议...

    java多线程之wait(),notify(),notifyAll()的详解分析

    Java多线程编程中,`wait()`, `notify()`, 和 `notifyAll()` 是三个非常重要的方法,它们用于线程间通信和同步。这些方法并不是定义在 `Thread` 类中的,而是作为 `Object` 类的一部分,这意味着任何Java对象都可以...

    多线程sleep,yield,wait区别

    `sleep()` 适用于需要让线程暂时退出执行的情况,`yield()` 用于尝试平衡多个线程的执行,而 `wait/notify/notifyAll()` 则用于线程间的协作,确保资源的有效共享。理解这些方法的差异和使用场景,能帮助开发者更好...

    java Thread & synchronized & concurrent 线程、同步、并发

    线程间通信主要通过`wait()`, `notify()` 和 `notifyAll()` 方法,以及`join()`方法来实现。此外,Java还提供了线程池(ExecutorService)来管理线程,以提高性能和减少资源消耗。 同步是多线程环境下保证数据一致...

    Thread Test result output

    根据给定的文件信息,我们可以深入探讨Java中的多线程同步机制,特别是关于`wait()`、`notify()`和`synchronized`关键字的使用及其在实际应用中的表现。此测试结果输出揭示了多线程环境中线程的启动、等待、唤醒以及...

Global site tag (gtag.js) - Google Analytics