GRVY
GRVY

Reputation: 55

How can I make use of the Lambda expression returned by spinServerUp() method in following code

I'm learning Java at the moment and I see some code that looks like this:

public interface Await {
    boolean await(long timeout, TimeUnit timeUnit) throws InterruptedException;
}
public Await spinServerUp() {
    this.startServers()
    return (timeout, timeUnit) -> countDownLatch.await(timeout, timeUnit);
}

Now, I understand that countDownLatch waits for the threads to complete before continuing on.

My question is - how do parameters timeout and timeunit get passed to the Lambda expression? I can't find any usage examples on my end for this block of code that I'm reading, so I'm a bit confused.

I'm also not sure if I follow the spinServerUp() method that well, I understand that it calls this.startServers() then returns the Lambda expression - thus giving control to the Lambda expression. Why return the Lambda expression, though?

I've tried to do some research and reading, but I got more confused. Any clarifications would be appreciated

Upvotes: 1

Views: 116

Answers (3)

Nick Allen
Nick Allen

Reputation: 1873

how do parameters timeout and timeunit get passed to the Lambda expression?

Just treat the returnValue as a function. Basically same as function you declared in class:

Await await = spinServerUp();
await.await(3, TimeUnit.SECONDS);

Why return the Lambda expression though?

Lambda function declaration does nothing util you call it like code snippet above.

The typical usage of lambda is callback. It is something that will happen if certain event is triggered (e.g. mouse clicked on a button). So it will not do anything if certain event is not triggered.

Or for a real world example. Jack told Nick to [call him] if Bob arrived. Call Jack is the lambda in this case and it will only be triggered if Bob arrived.

public ThingsToDo planForBobArriving() {
  String personToCall = "Jack";
  return () -> call(personToCall); 
}

public void mainLogic() {
  ThingsToDo thingsToDoWhenBobArrived = planForBobArriving();
  while(keepWaiting) {
    if (bobArrived()) {
       thingsToDoWhenBobArrived.execute(); // call Jack
       break;
    }
  }
}

Upvotes: 2

Alexander Ivanchenko
Alexander Ivanchenko

Reputation: 28988

Await is a Functional interface (i.e. an interface defining only a single abstract method).

And method spinServerUp() produces an implementation of this Functional interface (which is expressed in the form of Lambda expression).

Hence, in what ever place that requires an instance of Await you can use a Method reference intanceName::spinServerUp(), where intanceName is a reference to the instance of a class that own method spinServerUp(), also within the owning class you can use this keyword this::spinServerUp().

how do parameters timeout and timeunit get passed to the Lambda expression?

Suppose you have the following method:

public void foo(long timeout, TimeUnit timeUnit, Await a) {
    a.await(timeout, timeout);
}

You can call it like that:

foo(5, TimeUnit.MILLI_SCALE, intanceName::spinServerUp()

The parameters require by the Await contract should be provided by the code that uses it directly by invoking Await.await().

I understand that it calls the this.startServers() then returns the Lambda expression - thus giving control to the Lambda expression.

If you mean that you think that while spinServerUp() gets executed it also fairs the logic of the lambda expression, then it's not correct. A Lambda expression (as well a method references) is just a way to obtain an instance of a Function interface. Lambda basically is an object representing a certain behavior, when you're defining a lambda this behavior doesn't get executed.

In order to actually execute the behavior of a lambda expression, you need to plug the reference to it into a code which would invoke the abstract method of the Function interface it's represents (Await.await(), Function.apply(), Predicate.test(), etc.).

I recommend you to get familiar with these tutorials on Lambda expressions and Method references provided by Oracle

Upvotes: 2

MJG
MJG

Reputation: 409

You can use the lamda to invoke the await function:

try {
 if (spinServerUp().await(1, MINUTES)) {
   // do stuff
 }
} catch (InterruptedException e) {
 Thread.currentThread().interrupt();
// just exit on interruption?
}

Upvotes: -1

Related Questions