简介:

java中线程间同步的最基本的方式就是使用wait()&notify()&notifyAll(),它们是线程间的握手机制。除了上述方法,java5还在java.util.concurrent.Locks包中提供了condition接口,该接口声明了awake()&signal()方法,也是线程间同步的方式之一。 wait()/notify() 都是任意java object所具备的方法,它们通常与synchronized关键字配合使用,而condition一般与显式的重入锁配合使用。

语义:

Object.wait()把当前线程挂起,等待object.notify()或者object.notifyall()的执行。wait()可以替代busy waiting(通常以循环查询某条件是否已经具备的方式)。

object.notify()把等待object锁(monitor)的线程唤醒,通知其可以继续运行。如果有多个线程都在等待这个object的锁,则随机选择一个唤醒同时当前线程继续执行。当另外一个线程调用该java对象的notify()方法时,将“唤醒”等待该java对象的那个线程。

notifyAll()将唤醒所有在等待的线程;notify()仅唤醒一个正在等待的线程,如果有多个线程在等待,会随机选择一个唤醒。

Wait:

为了正确地执行object.wait()方法,当前线程必须已经获得了该object的锁。也就是说,只有在同步方法或者同步块(synchronized)中,才能调用wait方法。执行object.wait()方法意味着当前线程释放该锁,当前线程挂起,直到有另外线程执行object.notify()方法。  wait()有三种方式,带纳秒参数的::

  public final void wait(long timeout, int nanos) throws InterruptedException {

带毫秒参数的 :

  public final native void wait(long timeout) throws InterruptedException;

和不带参数的:

  public final void wait() throws InterruptedException {

其中wait()使用的比较多。

纳秒级的等待?

看wait的第一种实现,很有意思:

     public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
} if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
} if (nanos > 0) {
timeout++;
} wait(timeout);
}

nanos好像并没有发挥什么作用。 这是Java8在Windows平台下的JDK的源码。注意如果是实时操作系统的话,nanos就有可能发挥作用,但是在Windows下,nanos目前并没有发挥作用。这是因为虽然cpu的时钟周期是纳秒级的,但是Windows操作系统并不支持这么细粒度的时间间隔。

在调用wait时还有一点要特别注意:

 永远在一个循环中调用wait()方法。因为如果多个线程都在等待同一个锁,然后其中一个得到了这个锁,然后会重置等待的条件,然后其他线程需要在它们醒来以后检查循环条件,以此来决定它们是需要再次等待,还是开始执行。

notify:

为了调用某个java对象的notify()方法,你必须在同一个java对象上同步(synchronized),或者说在一个同步的上下文中:

 synchronized (someObject) {
someObject.wait(); // 释放锁,不对。应该在一个循环中调用wait方法
} /* different thread / object */
synchronized (someObject) {
someObject.notify();
}

尽量少使用wait/notify:

从Java5开始,java sdk中的java.util.conconrrent包中主要提供了三种与线程同步(不是synchronization,不是lock之类的线程互 斥)相关的类: Executor相关框架、并发容器(BlockinQueue)、和一些同步工具(Synchronizers,倒计数锁存器等)。这些同步工具主要是通用的同步类,主要用于线程间的协作。同步工具主要包括Condition、CountdownLatch、CyclicBarrier、Semaphore、CyclicBarrier、phasersexchangers等。

一般而言,在java5或者更新的java版本中,wait()&notify()很少显式地使用。因为很多标准库中的类已经实现了wait()/notify()的功能。比如:

  • 在Java5中,可以使用新的BlockingQueue实现,来实现生产者和消费者模型。
  • Java5中的显式锁类,比标准的synchronized关键字提供了更多的功能,比如带超时的tryLock。在Java5之前这个功能需要使用 wait()/notify()才能实现;
  • 可以使用Semaphore控制资源池。

操作系统线程问题中的概念

关键段CS critical section、事件Event、互斥量Mutex  信号量等概念 如何与java多线程中的概念映射???

互斥量:

跟锁的概念十分类似。

信号量:

操作系统的信号量是个很重要的概念,在进程控制方面都有应用。Java 并发库 的Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,acquire()获取一个许可,如果没有就等待,而 release()释放一个许可。比如在Windows下可以设置共享文件的最大客户端访问个数。

Semaphore维护了当前访问的个数,提供同步机制,控制同时访问的个数。在数据结构中链表可以保存“无限”的节点,用Semaphore可以实现有限大小的链表。另外重入锁ReentrantLock也可以实现该功能,但实现上要复杂些,代码也要复杂些。

参考文献:

http://blog.csdn.net/zyplus/article/details/6672775

http://javamex.com/tutorials/synchronization_wait_notify.shtml

http://www.javamex.com/tutorials/synchronization_producer_consumer.shtml

http://www.javamex.com/tutorials/synchronization_producer_consumer_2.shtml

http://www.javamex.com/tutorials/synchronization_concurrency_semaphore.shtml

http://blog.csdn.net/zyplus/article/details/6672775

http://www.javamex.com/tutorials/synchronization_wait_notify.shtml

http://blog.csdn.net/morewindows/article/details/7481609

http://blog.csdn.net/morewindows/article/details/7442639

http://blog.csdn.net/morewindows/article/details/7445233

http://blog.csdn.net/morewindows/article/details/7442333

http://stackoverflow.com/questions/6553225/whats-the-purpose-of-sleeplong-millis-int-nanos

Java并发之(2):线程通信wait/notify(TIJ_21_5)的更多相关文章

  1. java并发编程基础——线程通信

    线程通信 当线程在系统内运行时,程序通常无法准确的控制线程的轮换执行,但我们可以通过一些机制来保障线程的协调运行 一.传统的线程通信 传统的线程通信主要是通过Object类提供的wait(),noti ...

  2. Java并发编程原理与实战二十一:线程通信wait&notify&join

    wait和notify wait和notify可以实现线程之间的通信,当一个线程执行不满足条件时可以调用wait方法将线程置为等待状态,当另一个线程执行到等待线程可以执行的条件时,调用notify可以 ...

  3. java多线程 -- Condition 控制线程通信

    Api文档如此定义: Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对 ...

  4. java 多线程 day13 condition 线程通信

    /** * Created by chengtao on 17/12/5. * Condition 类似 wait和notify,解决线程间的同步问题 */ import java.util.conc ...

  5. Java并发之ThreadPoolExecutor 线程执行服务

    package com.thread.test.thread; import java.util.concurrent.ExecutorService; import java.util.concur ...

  6. java并发之停止线程

    停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作.停止一个线程可以用Thread.stop()方法,但最好不要用它.虽然它确实可以停止一个正在运行的线程,但是这个方法是不安 ...

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

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

  8. 【Java并发编程】:使用wait/notify/notifyAll实现线程间通信

    在java中,可以通过配合调用Object对象的wait()方法和notify()方法或notifyAll()方法来实现线程间的通信.在线程中调用wait()方法,将阻塞等待其他线程的通知(其他线程调 ...

  9. Java并发之线程间的同步协作与通信协作

    1,Monitor监视器与syncrhoized实现原理 1.1:Monitor Monitor是一个同步工具,相当于操作系统中的互斥量(mutex),即值为1的信号量. 它内置与每一个Object对 ...

随机推荐

  1. h5新增属性本地存储

    ---恢复内容开始--- 存储的两种类型: localStorage 和 sessionStorage localstorage:没有时间限制的数据存储 sessionStorage  针对一个ses ...

  2. Don't let anyone tell you different.

    Don't let anyone tell you different.不要让任何人否定你的与众不同.

  3. cron 任务执行表达式

    1.来源 开始我还不知道cron到底来源于哪里,不求甚解的我也没做过多了解,现在突然用到所以写一下. cron计划任务  其实只是linux 一个执行计划的一个工具或者执行程序. 在Linux系统中, ...

  4. Windows 10 下使用Git

    事实上,比在Linux下要难很多.不仅仅是因为Linux下CMD功能较弱,还有就是国内的网络环境,至少,我这Github Windows安装时,总是会下载无法完成 Github Desktop 虽然, ...

  5. Oracle数据库基础--SQL查询经典例题

    Oracle基础练习题,采用Oracle数据库自带的表,适合初学者,其中包括了一些简单的查询,已经具有Oracle自身特点的单行函数的应用 本文使用的实例表结构与表的数据如下: emp员工表结构如下: ...

  6. 使用NIO快速复制Java文件

    package com.test.test; import java.io.File;import java.io.FileInputStream;import java.io.FileOutputS ...

  7. LeetCode Valid Anagram (简单题)

    题意: 给出两个字符串s和t,判断串t是否为s打乱后的串. 思路: 如果返回的是true,则两个串的长度必定相等,所有字符出现的次数一样.那么可以统计26个字母的次数来解决,复杂度O(n).也可以排序 ...

  8. Android(java)学习笔记91:Eclipse中代码提示去掉@override,不然就报错!

    1. Eclipse中提示去掉@Override 把项目下载下来后有@Override的注释的方法会报错,如果把@Override去掉就不报错了.经过查阅后发现:@override注释在jdk1.5环 ...

  9. Being a Good Boy in Spring Festival(博弈)

    Being a Good Boy in Spring Festival Problem Description一年在外 父母时刻牵挂春节回家 你能做几天好孩子吗寒假里尝试做做下面的事情吧 陪妈妈逛一次 ...

  10. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第五节

    原文链接 第五节:了解和使用共享内存(2) Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个国家级的实 ...