1

I am having hard time converting old fashioned wait notify with spurious waits to java.util.concurrent API

First Problem: What to use, Future or CountdownLatch or CyclicBarrier according to this question

Second Question: How to use it? Because in all the examples I have looked at are converting a single async method to sync which is not a problem

Thirdly: What is the best option in my case out of Future task's get method, CountDownLatch or CyclicBarrier, since I dont have multiple threads, but only 2.

My async code

Main class:

public static void main(String[] args) throws InterruptedException {
    Request req = new Request(1);
    Thread tReq = new Thread(req);
    tReq.start();

    synchronized(req){
        req.wait();
    }
    LogProperties.log.info("Response is: " + req.responseString);
}

Request Class:

public class Request implements Runnable {

private int requestID;
public boolean isComplete;
public String responseString;

public Request(int id) {
    this.requestID = id;
}

@Override
public void run() {
    FutureTest.hmTest.put(requestID, this);
    try {
        //simulate a request
        Thread.sleep(10000);
    } catch (InterruptedException ex) {

    }
    Response response = new Response(requestID);
    Thread tResponse = new Thread(response);
    tResponse.start();
}

}

Response Class:

public class Response implements Runnable {

int id;

public Response(int responseId) {
    this.id = responseId;
}

@Override
public void run() {
    Request req = (Request) FutureTest.hmTest.get(id);
    req.isComplete = true;
    req.responseString = "Request for id [" + id + "] has been completed";
    synchronized(req){
        req.notify();
    }
}

}

My Problem with using future callable and CyclicBarrier is that Im not returning a variable, I want to wait on a object, which is of type Request in this case, so what is the best solution

Community
  • 1
  • 1
shabby
  • 3,002
  • 3
  • 39
  • 59
  • 1
    A `Future` is a different thing (are you expecting return values from your `Threads` / `Callables`?). If you have to *reset* the counter, use `CyclicBarrier` else a `CountDownLatch` will do. – TheLostMind Jan 20 '15 at 09:35

2 Answers2

3

One of the most versatile means for threads to communicate is a BlockingQueue.

In your case, you have one thread that creates a "response" (i.e., a producer), and you have another thread that is waiting for the "response" (a consumer). One way to implement that is for the producer to put() the response into a BlockingQueue, and have the consumer take() the response out of the queue.

The take() operation will implicitly wait for the response to become available before it returns.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
  • thanks for your response, but doesnt the BlockingQueue sound for multiple threads? Do you think it best suits for this consumer producer problem? I dont think it fits consumer/producer as much as the wait / notify does, the only problem with wait/notify being no wait-timeout handling and spurious waits. Plus I think if you are suggesting BlockingQueue, then Countdownlatch is also not any less applicable, but then i see that countdownlatch is also used in the case where multiple workers report to a single waiting thread, which collects the response – shabby Jan 20 '15 at 16:09
  • @shabby There isn't any _problem_ with wait()/notify(). You only need to know that wait() and notify() are low-level operations that are meant to be used in a very specific way, to solve a very specific problem. http://stackoverflow.com/questions/5999100/is-there-a-block-until-condition-becomes-true-function-in-java/26218153#26218153 – Solomon Slow Jan 20 '15 at 19:19
  • @shabby, "doesn't the BlockingQueue sound [?] for multiple threads?" Sound _like_...? Sound like overkill? Not at all. Communication between multiple threads is the raison d'être for BlockingQueue. It doesn't make any sense at all for a queue to be "blocking" if it's only used by one thread. Suppose the only thread in the program gets blocked in `q.put()` or in `q.take()`. Who's going to unblock it? – Solomon Slow Jan 20 '15 at 19:23
  • Does a queue sound like overkill for passing just one object? Not to a practicing software engineer! It's a simple solution that gets the job done. The fact that it can also work to solve bigger problems does not in any way disqualify it from being used to solve a small problem. – Solomon Slow Jan 20 '15 at 19:25
1

I think Pipes can be ideal for this, it can achieve synchronous communication easily.

Check out this link with pipes for producer consumer problem- http://www.informit.com/articles/article.aspx?p=26326&seqNum=10