0

In Java I have a program similar to as follows:

public void asyncLambda(Notifier notifier)
{
    DataUtil.getDataAsync((data) -> {
        // This code would be called on a new thread.
        for(Object o : data)
        {
            notifier.notify(o);
        }
    });
}

This compiles and runs (as far as I can tell). What I am curious about is what notifier object I am using.

The possibilities that I can think of are

  • A reference to notifier at the time of the original call is passed into the lambda.
  • When the lambda code is executed it gets moved back into the current stack frame of the function, even if the function is being called by a different caller (thereby meaning that notifier is now different).
  • The entire stack frame is copied into the new thread (this is sort of similar to the first possibility, but now all variables that may exist are also over there).
vandench
  • 1,973
  • 3
  • 19
  • 28
  • 1
    When the lambda is created, the value of the `notifier` is closed into the lambda. It's no different from if you did it "longhand" with an anonymous class. – Andy Turner Jun 06 '18 at 15:36
  • Interesting I think that this didn't compile unless `notifier` is declared `final` as to make the semantic outside and inside the lambda unambiguous. Has this changed in the latest versions of the language? – Valentin Ruano Jun 06 '18 at 17:36
  • I did a small test and if I tried to use a non-final variable in a lambda that in modified in its scope code then I get the following comp. error: "error: local variables referenced from a lambda expression must be final or effectively final" So basically the compiler allows you to access it as long as it can determine that in practice is not going to be modified, so is effectively a final variable. – Valentin Ruano Jun 06 '18 at 20:14
  • The code segment I am using compiles. I already know about the whole final and effectively final stuff. I was wondering about what will happen in a multithreaded environment. – vandench Jun 06 '18 at 20:18
  • Re, "wondering about what will happen in a multithreaded environment." Nothing special will happen. The lambda captures the value of `notifier` (i.e., it captures a reference to a particular `Notifier` instance) at the moment when it is created, and it will continue to refer to that same instance regardless of how many times it is called or, in which thread(s) it is called. – Solomon Slow Jun 06 '18 at 20:45
  • Nominated this question to be re-opened because the "duplicate" question does not ask about threads. Some of the answers talk about threads in explaining why lambdas work they way they do, but the question title might not draw the attention of somebody who was searching specifically about how to use lambdas in a multithreaded program. – Solomon Slow Jun 06 '18 at 20:53
  • There is nothing special about lambdas in threads. The value of `notifier` is copied into the lambda and it is used there. If the lambda is invoked from multiple threads concurrently then the `Notifier` needs to be thread-safe or you'll run into issues. Same as with any other type of code using another object concurrently from multiple threads. – Erwin Bolwidt Jun 07 '18 at 03:10

0 Answers0