Object类中有关线程通信的方法有两个notify方法和三个wait方法,官方解释:

void notify()

Wakes up a single thread that is waiting on this object's monitor.
void notifyAll()

Wakes up all threads that are waiting on this object's monitor.
String toString()

Returns a string representation of the object.
void wait()

Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.
void wait(long timeout)

Causes the current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed.
void wait(long timeout, int nanos)

Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed.

  这些方法都是final类型的,不能被子类重写。

  调用wait()和notify()方法的前提是,线程调用这两个方法时,拥有当前对象的monitor,即锁。所以,这两种方法的调用必须放在synchronized方法或synchronized块中。

  wait()与sleep()的比较:调用wait()后,当前线程失去了对象的monitor,必须被其他线程唤醒或设定的等待时间已超时,才能继续执行,并且被唤醒后,该线程并不会马上继续运行,而是放在线程就绪队列中,与其他线程公平竞争,获取对象的monitor。调用sleep()后,当前线程仍用够对象的monitor,当设定的睡眠时间超时后,线程会马上继续执行。

  一个线程变为一个对象的锁的拥有者,可以通过三种途径:

    1. 运行这个对象的synchronized的实例方法。
    2. 运行这个对象的synchronized的语句块。
    3. 对于Class类的对象,运行类的synchronized、static的方法。

假设有两个线程A和B公用一个NumberControl的类的对象,类结构如下:

public class NumberControl
{
private int number; public synchronized void increase()
{
if (0 != number)
{
try
{
wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
number++;
System.out.println(number);
notify();
} public synchronized void decrease()
{
if (0 == number)
{
try
{
wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
number--;
System.out.println(number);
notify();
}
}

NumberControl

  A线程执行对象的increase()方法,如果number为1,则线程等待。B线程执行对象的decrease()方法,如果number为0,则线程等待。然后执行A、B线程,得到的结果,number回程1、0、1、0的交替变化。

  但需要注意的是,如果在添加更过的线程共享这个对象,假设是4个线程A、B、C、D,A和C线程调用increase()方法,B和D线程调用decrease方法,再去试图让number得到1、0的交替变化,那当线程被唤醒后,仍需判断number的状态,是1还是0,因为在同一个对象中,当一个线程执行notify()时,被唤醒的线程是被随机挑选出来的。可能出现的情况是,B、C、D线程都处于等待状态,A状态执行完notify()方法,此时number是1,B、C、D其中任意一个都有可能被唤醒,如果C被唤醒,但C没有再去判断number的状态,那C将继续去执行,则number会继续增加,变为2,出现了不需要的结果。所以在判断语句中,不要使用if(),而是使用while()语句来判断number的状态,这样就可以避免异常状态的出现。

void notify()

Wakes up a single thread that is waiting on this object's monitor.
void notifyAll()

Wakes up all threads that are waiting on this object's monitor.

Java线程通信——wait() 和 notify()的更多相关文章

  1. 第23章 java线程通信——生产者/消费者模型案例

    第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...

  2. Java线程通信

    Java线程通信 螣蛇乘雾,终为土灰. 多个线程协同工作完成某个任务时就会涉及到线程间通信问题.如何使各个线程之间同时执行,顺序执行.交叉执行等. 一.线程同时执行 创建两个线程a和b,两个线程内调用 ...

  3. 多线程一共就俩问题:1.线程安全(访问共享数据) 2.线程通信(wait(),notify())

    多线程一共就俩问题:1.线程安全(访问共享数据) 2.线程通信(wait(),notify()) 1.线程安全,无非就是加锁,访问共享资源时,synchronized 2.线程通信,就是控制各个线程之 ...

  4. Java 线程通信

    线程通信用来保证线程协调运行,一般在做线程同步的时候才需要考虑线程通信的问题. 1.传统的线程通信 通常利用Objeclt类提供的三个方法: wait() 导致当前线程等待,并释放该同步监视器的锁定, ...

  5. java线程通信与协作小结 多线程中篇(十六)

      在锁与监视器中我们对Object中的方法进行了简单介绍 以监视器原理为核心,三个方法:wait,notify.notifyAll,可以完成线程之间的通信 当然,不会像“语言”似的,有多种多样的沟通 ...

  6. Java线程通信-生产者消费者问题

    线程通信示例——生产者消费者问题 这类问题描述了一种情况,假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中的产品取走消费.假设仓库中没有产品,则生产者可以将 产品放入仓库,有 ...

  7. 9.线程通信wait、notify

    线程之间通信 1.线程是操作系统的独立的个体,但这些个体如果不经过特殊处理就不能成为一个整体. 2.使用wait.notify,方法实现线程通信(2个方法都是需要object方法) 3.wait(释放 ...

  8. java——线程的wait()和notify()

    这是一个关于生产者和消费者的线程通信的例子: package thread_test; public class PCThread { public static void main(String[] ...

  9. JAVA线程通信之生产者与消费者

    package cn.test.hf.test3; import java.util.concurrent.locks.Condition;import java.util.concurrent.lo ...

随机推荐

  1. XAML设计器卡死

    在生成工程时,存在这样一个记录: “未能找到一个或多个间接引用的程序集.分析不需要这些程序集.但是,如果没有这些程序集,分析结果可能不完整”. 表现形式既不是错误,可也不是警告.之所以关注到这个问题, ...

  2. 配置多个Log4net实例

    应用场景: 控制软件工程拆分为多个子项目,在开发阶段希望每个子项目的日志是单独的.同时又希望日志统一集中定义在Tools(Tools为工具类项目,生成Tools.dll)下,而不是分散在各个子项目中. ...

  3. 实现 kindle 原生系统、多看系弹出注释的通用写法

    入手 Kindle 后开始自己做 ePub,之前一直用原生系统,使用的弹出注释代码如下: <p class="P_Footnote" id="ref_footnot ...

  4. highchairts柱状图显示数值并且带单位

    $(target).highcharts({ chart: { type: 'bar' }, colors: [ "#1ab394" ], title: { text: title ...

  5. Wonderful Sentense

    1.Sorry if I might sound arrogant or offensive. 2.Any further question? 3.How dare you! 4.Try it if ...

  6. [CAMCOCO][C#]我的系统架构 总图

    之前写的感觉有点乱,把架构的设计图先放上来吧,对照着说. CAMCOCO架构能够支持的模型: 1.B/S程序,比如CRM什么的,和访问普通网站没什么区别,都是从WEB服务器上进行操作: 2.APP的服 ...

  7. php操作mysql总结

    01  <?php02    $dbhost='localhost';03    $dbuser='root';04    $dbpass='123456';05    $dbname='pro ...

  8. PHP JS判断浏览器,微信浏览器

      微信内置浏览器的 User Agent 如何判断微信内置浏览器,首先需要获取微信内置浏览器的User Agent,经过在 iPhone 上微信的浏览器的检测,它的 User Agent 是: Mo ...

  9. JavaScript学习笔记 - 进阶篇(1)- JS基础语法

    前言 JavaScript能做什么? 1.增强页面动态效果(如:下拉菜单.图片轮播.信息滚动等) 2.实现页面与用户之间的实时.动态交互(如:用户注册.登陆验证等) JS进阶篇学习什么? 在JavaS ...

  10. iOS-单例模式-使用技巧

    SingleModel-单例模式 单例可以保证在程序运行过程,一个类只有一个实例(一个对象) 一般将单例设置成宏,这样在使用的时候可以很方便. 我们可以按照下面的步骤实现单例 1.自定义一个.h文件, ...