简介:

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

最新文章

  1. ubuntu16.04 orbslam ./build.sh 出错eigen
  2. J2EE之oracle、mysql存储过程调用
  3. android 和iOS的view上的区别
  4. alloc
  5. mysql中的if条件语句用法
  6. 使用DrawerLayout实现QQ5.0侧拉菜单效果
  7. ios开发之xcode6中如何添加pch全局引用文件
  8. repeater 分页显示数据
  9. Java面试宝典2014版
  10. 获取手机 IP
  11. [UWP]理解ControlTemplate中的VisualTransition
  12. Idea &#160;调试代码
  13. 【转】使用MySQL处理百万级以上数据时,不得不知道的几个常识
  14. [Swift]LeetCode653. 两数之和 IV - 输入 BST | Two Sum IV - Input is a BST
  15. Navicat 用ssh通道连接时总是报错 (报错信息:SSH:expected key exchange group packet form serve
  16. pycharm技巧
  17. XMPP接受发送消息
  18. 树上第k大联通块
  19. WPA3在2018年为无线安全添砖加瓦
  20. 一个网页的对象抽象之路——po编程 (干货,Java自动化测试)

热门文章

  1. 在数据绑定控件(如:Repeater)中使用if判断
  2. 绿卡基础知识:I-129
  3. 文件IO——将文件dfs的文件内容第三个字节之后的内容复制到文件dfd中
  4. Extjs4.1+desktop+SSH2 搭建环境 项目能跑起来
  5. POJ 3421 X-factor Chains(构造)
  6. 【BZOJ1965】[AHOI2005] SHUFFLE 洗牌(数学题)
  7. 进入Windows之前发出警告
  8. 1.VS Code 开发C#入门 安装Dotnet core
  9. C#冒泡排序程序
  10. 常用的ES6语法