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. POJ 2236 Wireless Network (并查集)

    Wireless Network Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 18066   Accepted: 761 ...

  2. 关于GrideView Item点击后出现错乱重叠的情况

    我在一个搜索页做了一个筛选信息的功能 大概思路如下:在根布局中用Include 引入一个筛选框(如图), 然后把边距设置为 android:layout_marginBottom="-250 ...

  3. C# 前台线程和后台线程

    进程会等待所有的前台线程完成后在结束工作,但是如果只剩下后台线程,则会直接结束工作 using System; using System.Collections.Generic; using Syst ...

  4. iOS 高阶

    1.UIStoryBoard 2. segue跳转传值 3. UIColor配色 //1. 十进制配色 [UIColor colorWithRed:163.0/255.0 green:148.0/25 ...

  5. 一次MVVM+ReactiveCocoa实践

    前言 学习MVVM和ReactiveCocoa(简称RAC)也有一段时间了,不过都仅限于看博客,一直对这两个东西很感兴趣,觉得很创新,也一直想找个机会在项目中实践一下,但是还是有一些顾虑,毕竟没有实践 ...

  6. iOS数据持久化(三)

    #pragma mark - Core Data stack /** * @synthesize 关联成员变量和属性 */ @synthesize managedObjectContext = _ma ...

  7. 【学习笔记】【C语言】选择结构-if

    1.if的第1种结构 if(条件) {     语句1;     语句2;     ...... } 如果if右边小括号()中的条件成立,也就是为“真”时,就会执行大括号{}中的语句: 如果条件为假, ...

  8. 20150506—WinForm自动生成按钮&按钮拖动

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  9. 20150226—C# winform中的ListView解析

    ListView在WinForm中多用于表的构建,可以直观的显示表的信息,其格式如同SQL的表 这是他的位置,在公共控件中: Listview的几个重要属性:Columms(集合).Groups(集合 ...

  10. 8个强大的基于Bootstrap的CSS框架

    做过前端开发的小伙伴们应该对Bootstrap不会陌生,它是由Twitter推出的开源CSS框架,其中包含了很多Web前端开发的工具包和应用组件.当然,和jQuery一样,Bootstrap同时也是一 ...