The below code is giving me a compile time error:
Thread t2 = new Thread(() -> { try { sleep(1000); } catch (InterruptedException e) {} });
The method sleep(int) is undefined for the type A (where A is my class name).
Whereas, when I use an anonymous inner class, there is no compile time error:
Thread t1 = new Thread(){ public void run(){ try { sleep(1000); } catch (InterruptedException e) {} } };
The below code also works fine:
Thread t3 = new Thread(() -> System.out.println("In lambda"));
How do things work inside a lambda expression body? Please help.
From many answers, I can see that the error can be resolved using Thread.sleep(1000)
in my first approach. However, I'd really appreciate if someone could explain to me how scope and context work in a lambda expression.
No. After starting a thread, it can never be started again. If you does so, an IllegalThreadStateException is thrown. In such case, thread will run once but for second time, it will throw exception.
according to thread life cycle, once thread is 'dead' you can not restart it. You only can start new thread invoking start() method. Thread can be bought to Running state from Runnable state not from Dead state.
A calling thread is the thread that calls a method or the thread inside which a method is called. If thread1 calls method methodA (if methodA gets called from within thread1 ) then the calling thread of methodA is thread1 . The listener argument specifies a callback method that will be called later in time.
The purpose of start() is to create a separate call stack for the thread. A separate call stack is created by it, and then run() is called by JVM. Let us see what happens if we don't call start() and rather call run() directly.
Thread.sleep
is a static method in the Thread
class.
The reason you can call sleep
directly without any qualifiers in an anonymous class is because you are actually in the context of a class that inherits from Thread
. Therefore, sleep
is accessible there.
But in the lambda case, you are not in a class that inherits from Thread
. You are inside whatever class is surrounding that code. Therefore, sleep
can't be called directly and you need to say Thread.sleep
. The documentation also supports this:
Lambda expressions are lexically scoped. This means that they do not inherit any names from a supertype or introduce a new level of scoping. Declarations in a lambda expression are interpreted just as they are in the enclosing environment.
Basically that is saying that inside the lambda, you are actually in the same scope as if you were outside of the lambda. If you can't access sleep
outside the lambda, you can't on the inside either.
Also, note that the two ways of creating a thread that you have shown here is intrinsically different. In the lambda one, you are passing a Runnable
to the Thread
constructor, whereas in the anonymous class one, you are creating a Thread
by creating an anonymous class of it directly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With