The key thing to know, is that threads aren’t a first-class kernel object. In OS kernels, there are only OS processes and memory regions.
To learn about threads, you should just learn about OS processes; and then learn that distinct OS processes can share memory regions between them, often via subprocess-spawn-time inheritance. Learn what fork(2) does on POSIX, and how it manages to be fast.
Starting with that intuition, it’s simple to then absorb what “threads” actually are: a usage pattern for spawning and managing OS processes that share memory; and a set of convenience APIs (that may be in-kernel, as in Windows; or purely in userland, as in Linux) for setting up this usage pattern. Everything these “threading” APIs can do, you can do yourself directly using the process-management and memory-mapping APIs. And those same calls are all that e.g. libpthread is doing.
Studying C, I haven't really come across threads other than trying out the things in `pthread.h`.
Would you recommend just reading the source code of that header for a better understanding?
It's old, but the material holds up well since it covers a lot of fundamentals
I think modern Java has better support for it, but if you've got mutable state spread throughout your application you're going to have a hard time no matter what.
How does one become a senior engineer if you don't understand concurrency?
Mutable state is most easily solved by having cpoies of everything, but then that's a tradeoff between performance and infrastructure/resource costs, but I guess that if you're in an all-Java shop that isn't much of an issue.
Best I can find as a source for now is https://www.youtube.com/watch?v=2y5Pv4yN0b0 -- I thought there was a link somewhere to Hickey himself saying this, but can't find it.