"Hi, Amigo! I want to tell you about sharing resources. Across different threads, naturally.
"I keep talking about the problems that happen when working with multiple threads and how to solve them. This doesn't mean that using threads is bad. Threads are a very powerful tool. In fact, they let you make your program faster and even more reliable. The more complex a program is, the more threads and various independent parts it has."
"Splitting a program into independent (loosely coupled) parts is very beneficial."
"Imagine that your program is internally divided into 100 threads. But you only have a dual-core processor. This means that on average 50 threads will be executed on each core."
"If you need to increase the program's performance, you just buy a dual-processor server and a couple of sweet processors for it. This could get you up to 32 cores, yielding a 2-20 times boost in performance. Depending on the number of truly independent parts it is divided into."
"This is one of the reasons why Java dominates in enterprise development. If a company has a complex internal program written by 20 developers, then it is much cheaper to buy another server than to double the program's performance through optimization."
"So that's what it's all about."
"But! Every time a developer decides to use another thread, he solves one problem and creates two. More and more threads won't endlessly increase the program's performance."
"First, any program has work that can't be broken apart and run in parallel on different threads. Second, all the threads are executed on the same processor. The more threads you have, the slower each one works."
"And, most importantly, threads often use the same objects (usually called 'shared resources')."
"For example, a thread wants to save information about work it has completed in a file. If there are several such threads and they want to write information to the same file, they will interfere with each other. To prevent the file from becoming a jumbled mess, access to the file is limited, i.e. while one thread uses the file, others wait."
"Yes, I remember. You do that using the synchronized keyword."
"And what if the threads are writing to different files?"
"Formally, these are different objects, but they are probably on the same hard drive."
"So, is it really possible to parallelize something inside the processor?"
"Technically, yes, but as soon as your thread needs something besides the data it has, that something might already be occupied by another thread—and your thread will have to wait."
"Well, what should I do then? How do I know if I should make a lot of threads or not?"
"This is determined directly by your program's architecture. Every project has its own 'architect' who knows all the 'resources' used in the program, knows their limitations, and how well/poorly they are parallelized."
"And if I don't know?"
"There are two options:"
a) work under the supervision of someone who does
b) get some lumps figuring it out on your own
"I'm a robot: I don't get lumps—only dents."
"Well, then, get some dents."
"I see. Thanks. You clarified some things that I had already started to wonder about."