concurrency and hardware
Preemptive multithreading is usually implemented by the operating system using timer interrupts.  Everything else can be done in software.  Even the timer interrupts aren't strictly necessary: in cooperative multithreading (what they had in Windows 3.1 and earlier and MacOS prior to MacOS X) the operating system would perform the thread switch whenever a thread did a system call (e.g. a file read or write.)

A process has an address space with one or more threads running in it.  Address spaces typically require hardware support for page tables.

There is no hardware support required for synchronization or communication.  Multiple threads in the same process communicate through the address space they share.  Threads within the same process typically synchronize using mutexes and condition variables.  Mutexes and condition variables can be implemented with load and store instructions.  (For the most part.  There are some processors that don't have sequentially consistent memory hardware, and for those the processor also needs to implement some kind of memory barrier instructions.)  When a thread needs to wait for a long time it will put itself to sleep by calling into the operating system.

Threads in different processes typically communicate through one of the abstractions implemented by the operating system (pipes, files, sockets).