Concurrent programming and Parallel programming. These two are somewhat similar.
Simply put, they both mean “executing multiple pieces of code at the same time“. So, have you ever thought like this?

Which is better: concurrent programming or parallel programming?
In fact, this question itself is off the mark . There is a big difference between concurrent and parallel, and it cannot be simply compared.
Concurrent and Parallel processing in everyday life
First, let’s imagine it in everyday life. A situation where you have to do two things at the same time.
Concurrent Processing: do the cooking while you do the laundry




Put the laundry into the washing machine, turn it on and start washing.
While the washing machine is running, you have some free time. Use that time to prepare lunch.
This task is executing “laundry” and “cooking” at the same time . This is Concurrent Processing.
Parallel Processing: Get the job done together


Once lunch is over, it’s time to clean up. You want to get it done quickly, so work together to wash the dishes.
Two people working together on the task of “washing dishes” is Parallel Processing.
Different approaches to time saving
Cooking while doing the laundry, or cleaning up together. The goal in both cases is to get housework done quickly!
But the way we think about it is different.
- Parallel processing (cooking while doing laundry): Use the time between doing laundry to cook and save time
- Parallel processing (cleaning up together): Two people can wash dishes at the same time to save time
That is, you can say it like this.
- Concurrent Processing is the effective use of free time.
- Parallel Processing means multiple people working on the same task at the same time.
Let’s try it out in a program
Next, let’s think about it in terms of actual programming: “Execute multiple codes simultaneously to save time“.
Sequential execution program
This is a simple Python program that displays the letter of the week in both Japanese and English.
# Count weeks in Japanese
def count_weeks_japanese():
weeks = ["日", "月", "火", "水", "木", "金", "土"]
for week in weeks:
print(week)
# Count weeks in English
def count_weeks_english():
weeks = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
for week in weeks:
print(week)
# Main process
def main():
count_weeks_japanese()
count_weeks_english()
if __name__ == "__main__":
main()
The result is this.
日
月
火
水
木
金
土
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
It’s nothing special, just a normal program.
Concurrent program
Now let’s turn this into a concurrent program. It will display Japanese and English at the same time. We will use a package called asyncio.
import asyncio
# Count weeks in Japanese
async def count_weeks_japanese():
weeks = ["日", "月", "火", "水", "木", "金", "土"]
for week in weeks:
print(week)
await asyncio.sleep(1) # 1秒待機
# Count weeks in English
async def ccount_weeks_english():
weeks = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
for week in weeks:
print(week)
await asyncio.sleep(1) # 1秒待機
# Main process
async def main():
tasks = [count_weeks_japanese(), ccount_weeks_english()]
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(main())
The result is this.
日
Sunday
月
Monday
火
Tuesday
水
Wednesday
木
Thursday
金
Friday
土
Saturday
The output is now alternated. This means that the two functions are running at the same time. This is concurrent processing.
Parallel program
Next is parallel processing. This time, let’s do it in Java. We’ll use ExecutorService.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ParallelExecution {
public static void main(String[] args) {
// // Create a thread pool
ExecutorService executor = Executors.newFixedThreadPool(2);
// Register tasks for parallel execution
executor.execute(ParallelExecution::countWeeksJapanese);
executor.execute(ParallelExecution::countWeeksEnglish);
// Wait for all tasks to complete and shut down the ExecutorService
executor.shutdown();
}
// Count weeks in English
public static void countWeeksJapanese() {
String[] weeks = {"日", "月", "火", "水", "木", "金", "土"};
for (String week : weeks) {
System.out.println(week);
try {
Thread.sleep(1000); // Wait for 1 second
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// Count weeks in English
public static void countWeeksEnglish() {
String[] weeks = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
for (String week : weeks) {
System.out.println(week);
try {
Thread.sleep(1000); // Wait for 1 second
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Here are the results.
日
Sunday
月
Monday
火
Tuesday
水
Wednesday
Thursday
木
Friday
金
Saturday
土
Here too, two functions are in action.
Oh…? There are some places where the results don’t alternate.
水
Wednesday
Thursday
木
What is going on?
Differences in program behavior
Let’s try to imagine how each program works.
Sequential execution program: Execute in order
A normal sequential program. count_week_japanese runs, and when it finishes, count_week_english runs. That’s normal.


Parallel programs: Executing while passing the baton
Next, parallel processing. The key is await asyncio.sleep.
# 日本語で週を数える
async def count_weeks_japanese():
weeks = ["日", "月", "火", "水", "木", "金", "土"]
for week in weeks:
print(week)
await asyncio.sleep(1) # 1秒待機
# 英語で週を数える
async def ccount_weeks_english():
weeks = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
for week in weeks:
print(week)
await asyncio.sleep(1) # 1秒待機
cWhen you print one in count_weeks_japanese, it goes to sleep. Then count_weeks_english starts working.
When one goes to sleep, the other starts moving. By repeating this process, they operate in a baton-passing fashion.


In other words, parallel processing makes it look like the processes are running simultaneously. Therefore, the results are always output alternately.
Parallel Programming: Truly works together
On the other hand, parallel programming in Java.
public static void main(String[] args) {
// スレッドプールの作成
ExecutorService executor = Executors.newFixedThreadPool(2);
// 並列実行するタスクの登録
executor.execute(ParallelExecution::countWeeksJapanese);
executor.execute(ParallelExecution::countWeeksEnglish);
// すべてのタスクの終了を待って、ExecutorServiceを終了
executor.shutdown();
}
Use executor.execute to launch two functions. The two functions run simultaneously.


Since they are displayed at different times, the output order sometimes changes.
The unit of execution that executes a program task is called a thread.
This Java program uses ExecutorService to run each function in two threads. This is called multithreading. Each thread runs independently.
Python, on the other hand, is single-threaded: it runs on a single thread and switches between tasks.
In what situations would you use it?
Concurrent and Parallel programs behave differently. Using the above description, it looks like this:
- Concurrent programming is a process that aims to reduce time by making effective use of free time.
- Parallel programming is a process that shortens time by executing multiple processes simultaneously.
実際には、どんなときに使うのでしょうか?
Concurrent Programming: For I/O Bound Tasks
Concurrent programming that makes effective use of free time. What is “free time”?
The downtime in programming occurs during input/output processing with the outside world.
- Reading and writing files
- Network Requests
- Waiting for User Input
For example, when you make a network request, there is a delay before the response comes back.
A process whose performance is limited by input/output is called an I/O bound task.
In between completing I/O bound tasks, your computer might do other things.
While you wait for the download from the network, it will also display an indication of how much is left, such as “xx% remaining“.
Concurrent programming is all about speeding up I/O bound tasks.
Parallel Programming: For CPU-bound tasks
Parallel programming, on the other hand, actually “executes multiple processes simultaneously”.
This is useful for processes that perform extensive calculations.
- Numerical calculations
- Image Processing
- AI Learning
For example, image processing. For an image that is 1,024 vertically and 1,024 horizontally, a massive calculation would be required: 1,024 x 1,024 = 1,048,576 times.
This type of processing, where computing power directly affects performance, is called a CPU-bound task. It is processing in which the CPU, the brain of the computer, does all the calculations.
There is no idle time during CPU-bound tasks, so to save time you need to run multiple tasks at the same time.
Parallel programming is all about shortening the time it takes to complete CPU-bound tasks.
The crucial difference between Concurrency and Parallelism
Concurrent processing and Parallel processing may seem similar, but they are different. From here, we will consider the major differences between the two.
The three crucial differences are:
- Concurrent processing is essential solution , and Parallel processing is one of the solutions
- Concurrency can also be achieved through parallel processing
- Some programming languages are not capable of parallel processing
Concurrent processing is “essential solutions” and Parallel processing is “one of the solutions”
Let’s use the previous example. Consider the process of downloading data from a network.
- Download the data
- During download, display the progress such as “xx% complete
“
If this is in the program specifications, it is necessary to realize two parallel processes: “download” and “progress display.”
Concurrent Processing is a problem that must be solved.
Let’s consider a different example.
- Correct a large number of large photos at once
Simply programming something that requires this much processing would take an enormous amount of time.
Here’s a way to cut down on this time:
- Calculate using a computer with high CPU performance
- Improve the processing algorithm
- Split the image into parts in parallel
Yes, you could bring in a really powerful machine. There are a number of solutions.
Parallel processing is just one solution among many.
Concurrency can also be achieved through Parallel processing
Let’s think back to parallel processing in everyday life.
Do the cooking while you do the laundry
This is an example of concurrent processing, but
Do the laundry, partner cooks
This can also be achieved with parallel processing by two people working together.




In other words, parallel processing is one way of achieving concurrency.
The difference between these two can also be expressed as follows.
- Concurrency is a problem domain – a problem of the shape of the problem itself
- Parallelism is about the solution domain – the means to solve the problem.
Some programming languages are not capable of parallel processing
For example, Python is known to be a programming language that is difficult to use in parallel processing.
Keep in mind that scripting languages often have limitations when it comes to parallel processing.
Summary
Concurrent programming, parallel programming. These are technologies that appear almost every day in modern programming.
However, it’s a concept that’s hard to grasp just by thinking about it in your head. Try writing lots of sample programs to get a feel for it.
Comments