Skip to content

Instantly share code, notes, and snippets.

@manimuttu
Created June 29, 2015 09:37
Show Gist options
  • Save manimuttu/4f5dad8dd89485a4e79b to your computer and use it in GitHub Desktop.
Save manimuttu/4f5dad8dd89485a4e79b to your computer and use it in GitHub Desktop.
Threads - Java Interview
1. What can multiple threads do that a single thread cannot?
First of all, threads cannot speed up execution of code. They do not make the computer run faster. All they can do is increase the efficiency of the computer by using time that would otherwise be wasted. In certain types of processing this optimization can increase efficiency and decrease running time.
The simple answer is yes. You can write any code to be run on a single thread. Proof: A single processor system may only run instructions linearly. Having multiple lines of execution is done by the operating system processing interrupts, saving the state of the current thread, and starting another one.
The complex answer is ... more complex! The reason that multithreaded programs may often be more efficient than linear ones is because of a hardware "problem". The CPU can execute calculations more quickly than memory and hard storage IO. So, an "add" instruction, for example, executes far more quickly than a "fetch". Caches and dedicated program instruction fetching (not sure of the exact term here) can combat this to some extent, but the speed issue remains.
Threading is a way of combating this mismatch by using the CPU for CPU bound instructions while IO instructions are completing. A typical thread execution plan probably would be: Fetch data, process data, write data. Assume that fetching and writing take 3 cycles and processing takes one, for illustrative purposes. You can see that while the computer is reading or writing, it's doing nothing for 2 cycles each? Clearly it's being lazy, and we need to crack our optimization whip!
We can rewrite the process using threading to use this wasted time:
#1 fetch
no operation
#2 fetch
#1's done, process it
write #1
#1 fetch
#2's done, process it
write #2
fetch #2
And so on. Obviously this is a somewhat contrived example, but you can see how this technique can utilize the time that would otherwise be spent waiting for IO.
Note that threading as shown above can only increase efficiency on heavily IO bound processes. If a program is mainly calculating things, there's not going to be a lot of "holes" we could do more work in. Also, there is an overhead of several instructions when switching between threads. If you run too many threads, the CPU will spend most of it's time switching and not much actually working on the problem. This is called thrashing.
That all is well and good for a single core processor, but most modern processors have two or more cores. Threads still serve the same purpose - to maximize CPU use, but this time we have the ability to run two separate instructions at the same time. This can decrease running time by a factor of however many cores are available, because the computer is actually multitasking, not context switching.
With multiple cores, threads provide a method of splitting work between the two cores. The above still applies for each individual core though; A program that runs a max efficiency with two threads on one core will most likely run at peak efficiency with about four threads on two cores. (Efficiency is measured here by minimum NOP instruction executions.)
The problems with running threads on multiple cores (as opposed to a single core) are generally taken care of by hardware. The CPU will be sure that it locks the appropriate memory locations before reading/writing to it. (I've read that it uses a special flag bit in memory for this, but this could be accomplished in several ways.) As a programmer with higher level languages, you don't have to worry about anything more on two cores as you would have to with one.
TL;DR: Threads can split work up to allow the computer to process several tasks asynchronously. This allows the computer to run at maximum efficiency by utilizing all the processing time available, rather than locking when a process is waiting for a resource.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment