If you are familiar with a language that either supports the Actor Model[0] natively, or has a library[1] that offers support for the model, I recommend trying to write concurrent applications using that.
I struggled with concurrency quite a bit until I stumbled upon the Akka framework for Scala. I was already familiar with Scala, so that made it easy to learn in terms of what I already knew. The Actor Model itself is a very simple concurrency model, and I think understanding that makes it easier to understand other concurrency paradigms.
To truly grok what you're getting into, I'd recommend watching Kevlin Henney's talk about concurrency[1]. The key quote
"when you introduce concurrency into a non-concurrent environment what you do is you change the laws of physics of your program, you change the nature of time"
2 comments
[ 3.0 ms ] story [ 11.9 ms ] threadI struggled with concurrency quite a bit until I stumbled upon the Akka framework for Scala. I was already familiar with Scala, so that made it easy to learn in terms of what I already knew. The Actor Model itself is a very simple concurrency model, and I think understanding that makes it easier to understand other concurrency paradigms.
[0] https://en.wikipedia.org/wiki/Actor_model
[1] https://en.wikipedia.org/wiki/Actor_model#Actor_libraries_an...
Also check out the references / further reading / external links on that wiki page for actual resources.