Q & A
-"Am i correct that the program flow will not move to the next line unless the unnable lambda is finished on current line? For example, unless the Runnable lambda finishes for s.o.p("printing zoo inventory")...it wont start the next Runnable lambda on next line?"
- Yes, you are correct.*
-"What happens in situation if the current thread executor line with a Runnable lambda that is computationally intensive? In this case, the
next line (if it contains another Runnable lambda)..would have to
wait until the current thread executor finishes the task?"
- Yes, it would have to wait.*
-"Your favorite color?"
-Red.
( * ) Assuming you are checking the behaviour from the ExecutorService, leaving out of the equation the main thread (and its invocation in order to execute something), and focusing on the pooled worker threads. The main thread runs by its own, and some implementations may also assign tasks to it if they decide to, that's why this note.
Test & Compare
I will try to compare this executor with a multithreaded one, in order to show the differences between both approaches.
Regarding your questions, which focus on the blocking-waiting scenario, the answers given differ completely based on the used executor service. Using the second option, the answers would be:
It will be able to move to the next line if a worker is avaliable, even if current line didn't finish.
No, it won't have to wait if a thread is avaliable.
Red.
SingleThreadExecutor
Creates an Executor that uses a single worker thread operating off an
unbounded queue.
Tasks are
guaranteed to execute sequentially, and no more than one task will be
active at any given time.
You only have a single thread on the pool, so all the tasks are assigned to it. It will have to sequentially execute them all, as stated on the docs. To make a simple test, for example:
service = Executors.newSingleThreadExecutor();
service.execute(() -> System.out.println("Printing zoo inventory"));
service.execute(() -> {
try {Thread.sleep(5000); System.out.println("Woke up"); }
catch (InterruptedException e) {e.printStackTrace();}
});
service.execute(() -> System.out.println("Finish"));
Output
Printing zoo inventory // ---- [Thread 1]
//...5s
Woke up // ---- [Thread 1]
Finish // ---- [Thread 1] -{x}-
As shown in this at least mediocre time graph:
{task1} {task2} {task3}
^ ^ ^
| | (~5s) |
[Thread1]-->[Thread1]---------------------->[Thread1]->{x}
Debugging it, the only avaliable thread affirmes it was the one that executed the previous two tasks. The image examples are from original OP's question:

Breakpoint at third task - already two completed

Using the FixedThreadPool for the example. The behaviour of the process changes when more than one worker thread is avaliable; For this example, two threads are set.
As always, the docs should be read carefully:

Creates a thread pool that reuses a fixed number of threads operating
off a shared unbounded queue. At any point, at most nThreads threads
will be active processing tasks. If additional tasks are submitted
when all threads are active, they will wait in the queue until a
thread is available
Modified the test a little bit, to add some info regarding the working threads and perform some extra tasks.
volatile boolean wifeAlarm = false;
//...
service = Executors.newFixedThreadPool(2);
Once set, execute multiple tasks:
service.execute(() -> System.out.println("Woke up fast -"
+ Thread.currentThread().getName()));
service.execute(() ->
{
try {
Thread.sleep(5000);
System.out.println("Woke up lazy - John where are you?? - {"+
Thread.currentThread().getName()+"}");
} catch (InterruptedException e){}
finally { wifeAlarm=true;}
});
service.execute(() -> System.out.println("Cleaning - {"
+ Thread.currentThread().getName()+"}"));
service.execute(() -> System.out.println("Making breakfast - {"
+Thread.currentThread().getName()+"}"));
service.execute(() -> System.out.println("Flirt with neighbour - {"
+Thread.currentThread().getName()+"}"));
service.execute(() -> System.out.println("Got her number - {"
+Thread.currentThread().getName()+"}"));
service.execute(() -> System.out.println("Send hot af pic - {"
+Thread.currentThread().getName()+"}"));
service.execute(() -> System.out.println("Remove all proof on phone - {"
+Thread.currentThread().getName()+"}"));
service.execute(() ->
{
try {
while (!wifeAlarm)
Thread.sleep(13);
System.out.println("Just working my love - {"+
Thread.currentThread().getName()+"}");
} catch (InterruptedException e) {}
});
Output
Woke up fast - {pool-1-thread-1}
Cleaning - {pool-1-thread-1}
Making breakfast - {pool-1-thread-1}
Flirt with neighbour - {pool-1-thread-1}
Got her number - {pool-1-thread-1}
Send hot af pic - {pool-1-thread-1}
Remove all proof on phone - {pool-1-thread-1}
// ~4-5s
Woke up lazy - John where are you?? - {pool-1-thread-2}
Just working my love - {pool-1-thread-1}
This is just another terrible representation:
{task1} {task2} {task3} (..) {task9}
^ ^ ^ ^ (~5s)
| [Thread2]--- | -------------|---------(...)----------->{x}
[Thread1] ----->[Thread1]--(..)-[Thread1]----------------------->{x}
In resume: John has taken advantage of this new context, achieving something great thanks to the multithreaded pool.

John is able to execute 7 actions while thread-2 executes 1. Even better for John, he's able to finish them all before thread-2 finished its assigned task. John is safe now, it will finish its task and go IDLE, as the queue is empty. Good for John.
thread-2 is assigned task 2. But this time the sleep won't lead to an increase on the work queue, as the other thread is able to concurrently execute them.
thread-1 executes all the 4 vital tasks: 5, 6, 7 and 8. It is also assigned the other 4 low priority tasks, being able to empty the work queue while the other thread was "busy" (sleeping).