In a concurrent program, the number of threads is set to a certain size:

Setting the number of threads too small may cause programs to underuse system resources.

If the number of threads is too large, it may cause excessive competition for resources, resulting in additional overhead for the system.

What is context switching?

In the era of single-core CPUS, operating systems were already capable of handling multi-threaded concurrent tasks. The processor assigns each thread a slice of CPU time, and the thread executes the task within that slice.

What is the concept of time slice?

Time slice is the CPU allocated to each program time, each thread is allocated a time slice, called its time slice, that is, the process is allowed to run time, so that each program from the surface is simultaneous.

The duration is usually tens of milliseconds.

If the process is still running at the end of the time slice, the CPU is stripped and allocated to another process. If the process blocks or ends before the time slice ends, the CPU switches immediately. Without wasting CPU resources.

Macro: We can have multiple applications open at the same time, each running in parallel. When we opened wechat, QQ, IDEA, database, etc., I could not feel the processor constantly switching time slices.

On the micro level: Since there is only one CPU, which can only handle part of the program’s requirements at a time, one way to deal with fairness is to introduce time slices, which each program executes in turn.

What is context switching?

When a thread runs out of time or is forced to pause for some other reason, another thread or process or thread of another process will be selected by the operating system and used to occupy the processor.

This process in which a thread is paused and a thread package is selected to begin execution is called a context switch.

And CPU registers, program counters

Context switching involves the storage of registers and the storage of instruction contents by program counters.

CPU registers store tasks that have been, are, and are about to be executed.

The program counter is responsible for registering where the CPU is executing an instruction and where the next instruction will be executed.

Context switching classification

  1. Context switching between processes.
  2. Context switching between threads (the focus of this article).

What scenarios can cause context switching of threads?

There are two types of thread context switches:

A spontaneous context switch is a thread that is cut out by a Java program call. In multithreaded programming, executing a call to a method or keyword in the figure above often causes a spontaneous context switch.

An involuntary context switch is a thread that is being pushed out due to the scheduler. Common examples are threads running out of allocated time slices, virtual machine garbage collection, or execution priority issues.

So why does virtual machine garbage collection cause a context switch?

In the Java Virtual machine, the memory of objects is allocated by the heap in the virtual machine. As the program runs, new objects are constantly created. If old objects are not reclaimed after use, the heap memory will be used up quickly. The Java virtual machine (JVM) provides a reclamation mechanism to reclaim objects that are no longer used after creation, ensuring a sustainable allocation of heap memory. The use of this garbage collection mechanism can lead to stop-the-world events, which are essentially thread pauses.

How do I detect context switches?

The vmstat command

You can use the vmstat command to view thread context switches.

Parameters that

procs

  • R: Number of processes running, etc.
  • B: The number of processes in the sleep state of the terminal.

memory

  • SWPD: virtual memory usage (unit: KB).
  • Free: indicates free memory (unit: KB).
  • Buff: Amount of memory used as cache (unit: KB).

swap

  • Si: Write size from swap area to memory per second.
  • So: the memory size written to the swap area per second.

io

  • Bi: Number of blocks read per second
  • Bo: Number of blocks written per second

system

  • In: Number of interrupts per second, including clock interrupts.
  • Cs: number of context switches per second.

CPU

  • Us: User process execution time
  • Sy: System process execution time
  • Id: idle time (including IO wait time), the idle time of the CPU. Expressed as a percentage.
  • Wa: Wait for I/O time

Pidstat command

Parameters that

  • CSWCH /s (voluntary) : A context switch that occurs when the value process is unable to obtain required resources, such as I/O, memory, and other system resources
  • NVCSWCH/S (involuntary) : Context switch occurs when a process is forcibly scheduled by the system due to time expired. For example, an involuntary context switch occurs when a large number of processes compete for cpus

conclusion

Context switching is the process by which a working thread is suspended by another thread and the other thread occupies the processor to start executing the task. System and Java program invocation operations, both spontaneous and involuntary, can lead to context switches, resulting in system overhead.

The more threads there are, the faster the system will run. So we usually in the case of large concurrency, when to use a single thread, when to use multithreading?

In general, we can use a single thread when the single logic is simple and relatively fast. For example, Redis, which we talked about earlier, reads values quickly from memory, regardless of the blocking problems caused by I/O bottlenecks. However, in the scenario where logic is relatively complex, waiting time is relatively long or a lot of calculation is required, I suggest using multi-threading to improve the overall performance of the system. For example, the NIO era of file read and write operations, image processing and big data analysis.