Java并发之(2):线程通信wait/notify(TIJ_21_5)
简介:
java中线程间同步的最基本的方式就是使用wait()¬ify()¬ifyAll(),它们是线程间的握手机制。除了上述方法,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、phasers和exchangers等。
一般而言,在java5或者更新的java版本中,wait()¬ify()很少显式地使用。因为很多标准库中的类已经实现了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
最新文章
- ubuntu16.04 orbslam ./build.sh 出错eigen
- J2EE之oracle、mysql存储过程调用
- android 和iOS的view上的区别
- alloc
- mysql中的if条件语句用法
- 使用DrawerLayout实现QQ5.0侧拉菜单效果
- ios开发之xcode6中如何添加pch全局引用文件
- repeater 分页显示数据
- Java面试宝典2014版
- 获取手机 IP
- [UWP]理解ControlTemplate中的VisualTransition
- Idea &#160;调试代码
- 【转】使用MySQL处理百万级以上数据时,不得不知道的几个常识
- [Swift]LeetCode653. 两数之和 IV - 输入 BST | Two Sum IV - Input is a BST
- Navicat 用ssh通道连接时总是报错 (报错信息:SSH:expected key exchange group packet form serve
- pycharm技巧
- XMPP接受发送消息
- 树上第k大联通块
- WPA3在2018年为无线安全添砖加瓦
- 一个网页的对象抽象之路——po编程 (干货,Java自动化测试)