Přepínání kontextu procesoru je mimochodem prakticky všechno, co musí dělat implementace threadů. Stačí každému threadu přidělit zásobník a CPU, což je kód, který může vykonávat i aplikace. Tedy pokud operační systém z nějakého důvodu nenabízí thready, aplikace si je může naprogramovat sama. Odtud pojmy user managed threads pro thready, které jsou implementovány v aplikaci a kernel managed threads pro thready, které jsou implementovány v kernelu. Jiná terminologie používá user threads pro thready, které jsou implementovány v aplikaci a kernel o nich neví, lightweight processes pro thready, které jsou implementovány v kernelu a aplikace je používá a kernel threads pro thready, které jsou implementovány v kernelu a aplikace o nich neví.
Snaha o efektivitu směřuje k user threadům. Pokud je jejich implementace součást aplikace, šetří se na overheadu volání kernelu, šetří se paměť kernelu, a vůbec je to pohodlnější, člověk si může třeba i ledacos doimplementovat, přepínání může být kooperativní bez problémů s robustností operačního systému.
Implementace user threadů musí řešit řadu komplikací. Protože přepínání user threadů má na starosti aplikace, pokud některá z nich zavolá kernel a zůstane tam, přepínání se zastaví. Pokud je přepínání preemptivní, může narazit na problémy s reentrantností knihoven či syscalls, typicky malloc. Thready se mohou vzájemně rušit skrz globální kontext, typicky errno, lseek, brk. Thready nemohou bez podpory kernelu použít více procesorů.