No, my definition is not exact, but I hope it was good enough to get the point across.
Technically, in the most pedantic sense, a "thread" is a unit of execution (a stack, a set of registers, and an instruction pointer). By that technical definition, a "thread" is a unit of concurrency, you are correct. "In the old days", it was known as _time slicing_. It is what is known as "pre-emptive concurrency". In other words, your program has no say in the matter. The Operating system just decides to pause your program and run another one. The operating system can decide to run your program on one physical CPU core, and then decide to move it to a different physical CPU core if it wants. Async is what is known as "cooperative concurrency". Your program, not the OS, gets to decide when it pauses and what code runs next. (via the "await" keyword.) Neither one is "parallel" in a _strict_ sense. Technically Parallel is a physical feature of hardware. There is no such thing as parallel software, there is only parallel hardware. That being said, when the common newbie or intermediate programmer refers to "threading", they usually are referring to using multiple cores on their CPU, i.e. parallelism. As a user program, you are actually not allowed to directly execute code on another core. You are only allowed to create a "thread", which the OS will then decide to run when and where it wants (usually on another core, but not guaranteed.) My point is that these two concepts complement each other very well, and we should have good API's for making them work together.
