Thursday, August 20, 2015

Java Wait and Notify



Using wait/notify to coordinate threads (latch)
public class Latch {
  private final Object synchObj = new Object();
  private int count;

  public Latch(int noThreads) {
    synchronized (synchObj) {
      this.count = noThreads;
    }
  }
  public void awaitZero() throws InterruptedException {
    synchronized (synchObj) {
      while (count > 0) {
        synchObj.wait();
      }
    }
  }
  public void countDown() {
    synchronized (synchObj) {
      if (--count <= 0) {
        synchObj.notifyAll();
      }
    }
  }
}

Using wait(), notify() and notifyAll() in Java: common problems and mistakes
  • 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.
http://lovestblog.cn/blog/2016/03/27/object-wait-notify/
当我们执行wait的时候让线程挂起,当执行notify的时候唤醒其中一个挂起的线程,那需要有个地方来保存对象和线程之间的映射关系(可以想象一个map,key是对象,value是一个线程列表),当调用这个对象的wait方法时,将当前线程放到这个线程列表里,当调用这个对象的notify方法时从这个线程列表里取出一个来让其继续执行,这样看来是可行的,也比较简单,那现在的问题这种映射关系放到哪里。而synchronized正好也是为线程间协作而设计的,上面碰到的问题它也要解决,或许正因为这样wait和notify的实现就直接依赖synchronzied(monitorenter/monitorexit是jvm规范里要求要去实现的)来实现了,这只是我的理解,可能初衷不是这个原因.

wait的线程是否会影响load

这个或许是大家比较关心的话题,因为关乎系统性能问题,wait/nofity是通过jvm里的park/unpark机制来实现的,在linux下这种机制又是通过pthread_cond_wait/pthread_cond_signal来玩的,因此当线程进入到wait状态的时候其实是会放弃cpu的,也就是说这类线程是不会占用cpu资源。


Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts