Using wait(), notify() and notifyAll() in Java: common problems and mistakes
2016-07-12 21:45
417 查看
Here are some limitations and common things that go wrong with the wait() / notify() paradigm in Java:
You need to check the condition before entering wait(), else you may never be notified.
Waking up from a wait() doesn't mean the condition you were waiting for has happened! So you generally need to wait in a loop until the condition holds (or until you decide to give up).
The timed wait waits forever if you pass in a zero wait time! So be careful to check for zero if you are calculating the wait time...!
Choosing notify() when notifyAll() is required can make threads stall.
Conversely, calling notifyAll() when only notify() is required is generally benign, but may reduce program throughput.
Calling wait() automatically releases the lock of the object you are waiting on, but does not release locks on other objects! So in the following case, the caller will still hold the lock to object1 during
the wait:
Calling notify() does not "transfer control" to notified threads immediately: it merely marks them as "runnable". A notified thread will not be able to run until the following things happen: (1) the notifying thread releases its lock on
the object being notified; (2) the thread scheduler next shcedules the notified thread. (On some systems such as Windows, this will happen fairly quickly, because threads are given a temporary priority boost when woken from a wait state, but it generally won't
happen until the next interrupt.)
The notify() / wait() paradigm is quite flexible, and allows a wide variety of common synchronization constructs (queues, resource pools, thread pools, barriers, read/write locks, semaphores...) to be created some way or other. Until Java
5, a disadvantage of Java as a platform is that it hasn't had library implementations of these constructs as standard. Goodness only knows how many Java implementations of queues, semaphores and thread pools there must be out there, with differing
degrees of bugginess.
Java 5 improves this situation by providing standard library implementations of well-tested, high performance synchronization constructs. On the next page, we'll see an example of using wait/notify
to implement a latch, and how Java 5 provides the CountDownLatch with this functionality.
You need to check the condition before entering wait(), else you may never be notified.
Waking up from a wait() doesn't mean the condition you were waiting for has happened! So you generally need to wait in a loop until the condition holds (or until you decide to give up).
The timed wait waits forever if you pass in a zero wait time! So be careful to check for zero if you are calculating the wait time...!
Choosing notify() when notifyAll() is required can make threads stall.
Conversely, calling notifyAll() when only notify() is required is generally benign, but may reduce program throughput.
Calling wait() automatically releases the lock of the object you are waiting on, but does not release locks on other objects! So in the following case, the caller will still hold the lock to object1 during
the wait:
synchronized (object1) { synchronized (object2) { object2.wait(); } }
Calling notify() does not "transfer control" to notified threads immediately: it merely marks them as "runnable". A notified thread will not be able to run until the following things happen: (1) the notifying thread releases its lock on
the object being notified; (2) the thread scheduler next shcedules the notified thread. (On some systems such as Windows, this will happen fairly quickly, because threads are given a temporary priority boost when woken from a wait state, but it generally won't
happen until the next interrupt.)
The notify() / wait() paradigm is quite flexible, and allows a wide variety of common synchronization constructs (queues, resource pools, thread pools, barriers, read/write locks, semaphores...) to be created some way or other. Until Java
5, a disadvantage of Java as a platform is that it hasn't had library implementations of these constructs as standard. Goodness only knows how many Java implementations of queues, semaphores and thread pools there must be out there, with differing
degrees of bugginess.
Java 5 improves this situation by providing standard library implementations of well-tested, high performance synchronization constructs. On the next page, we'll see an example of using wait/notify
to implement a latch, and how Java 5 provides the CountDownLatch with this functionality.
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树