Multithreading on AVR
To create an adequate multi-threading system, you need to do a 'context switch' see Wikipedia 'context switch' for an explanation.

The code needs to make the 'context switch' be 'invisible' to each thread. Otherwise a thread will not be possible to restart reliably, destroying the value of doing it.

To make an invisible context switch to any running thread all of its state needs to be saved. It isn't sufficient to just save the SREG (status register), and flip to another stack. It needs to save all registers that could possibly be in use. Clearly the obvious set is the entire AVR register file, 32 registers. They would need to be saved, and the register file for the thread about to be resumed loaded in such a way that everything will be restored to the same state at the point that thread was previously interrupted.

Summary: yes an AVR multi-threaded system could be built using a timer, however, your code needs to save and restore a lot more state.

As I said in my comment, an AVR running at its highest speed of 20MHz, needs one or more cycles to complete one instruction. It would take about 32 instructions, and hence 64 cycles to store all of the 32 registers into memory, and about 64 cycles more to load the registers for a different thread, plus a little bit more for IRS entry and exit. 

So, you should estimate about 140 cycles to create the most basic multi-threading context switch. That is 7µs at 20MHz clock. I'd suggest you keep the context switch well under 10% of the available CPU cycles so that it can actually get some useful work done. So have the interrupt less frequent than 70µs.

A possible place to help you understand the scope of the issues is to look at an existing simple OS. Then you will understand all of the other pieces which are likely to be needed more quickly. For example something like FreeRTOS.

This 'Arduino OS' forum page may help too.

A lot of the context switch code will need to be in assembler because you can't reliably get at the registers from C. However, because the AVR's instruction set is relatively simple, that shouldn't be too hard. 

Each thread is usually represented by several different chunks of memory (RAM):
1. The register values
2. The stack

Atmel's AVR don't have a lot of RAM, so one awkward part is allocating enough stack for the thread, without using so much memory that there isn't room for enough threads.

The last little wrinkle that I remember is an exit from ISR (RETI) isn't exactly the same as a return from subroutine (RET), so you'll need to think that through too.