that example is a good ones, as both measuring the temperature and updating the display have delays involved, which instead of taking the normal blocking arduino route and writing delay(10) or what ever is required, you could use a timer, and have each bit check to see if its time has been reached, and when it does, run,
so you start your temp measurement its code then adds whatever delay it required to the current timer value, while its waiting for that value to be reached the LCD loop moves the cursor and writes the last value, then adds its delay for the next loop, (each task has its own variable to compare against), sometime later the measurement completes, stores the value, and begins the next,
during those gaps between each piece of code running, you can shove in other tasks, with most example implementations you would need a task to delay the rest for a very long time to cause something to be missed (as its based on a comparison, it being late means it is run) to better explain myself, the micros timer on the arduino takes about 15 minutes to wrap around on itself, meaning a task would need to hold up the rest for over 15 minutes to make it miss running once,
this is also where blocking / non-blocking code comes in, as writing delay(10) simply means the processor can do nothing else during that time, but you know it will complete very predictably, while the time approach allows anything and everything to run in the gap or directly after another, but you can have some variance in how long it takes for a particular task to get a chance to run, (code written first runs first)