Java multithreading - how do threads come from?

The wide application of concurrent processing is the fundamental reason why amdahl's law replaces Moore's law as the driving force for the development of computer performance, and it is the most powerful weapon for human beings to squeeze computer computing power.

Concurrency does not necessarily have to be multi-threaded, and multi-process is also possible. However, when talking about concurrency in java, most of them are inseparable from threads. So let's start with threads. This article mainly includes the following contents:

implementation of the thread

thread scheduling

thread state switch

 

implementation of the thread

A thread is a more lightweight scheduling execution unit than a process. In Linux, there is no difference between a thread and a process. The only thing is that in the address space, the virtual memory space of thread switching is still the same, but process switching is different.

At present, the thread implementation provided by the mainstream operating systems, the thread implementation methods provided by java are all native, because different hardware and operating systems provide thread scheduling methods are not the same, so java does not use a platform-independent unified method to realise.

There are three main ways to implement threads: using kernel threads, using user threads, and using user threads and lightweight processes.

 

Kernel thread implementation

A kernel thread (KLT) is a thread directly supported by the operating system kernel, and this thread is performed by the kernel to complete thread switching.

Programs generally do not directly use kernel threads, but use a high-level interface of kernel threads—Lightweight Processes (LWPs). Lightweight processes are what we call threads. 1:1 correspondence between them.

 

advantage:

Directly supported by the kernel, created and revoked by the operating system kernel. The kernel maintains process and thread context information and thread switching. A kernel thread is blocked due to an I/O operation and will not affect the operation of other threads.

shortcoming:

 1. Thread operation, creation, synchronization, etc. all require system calls, and system calls are expensive and need to switch back and forth between user mode and kernel mode.

2. Each lightweight process needs a kernel thread to support it, and it needs to consume a certain amount of kernel resources.

 

User thread implementation

User thread refers to a thread that is implemented in a user program without kernel support. It does not depend on the operating system core. The application process uses the thread library to provide functions for creating, synchronizing, scheduling and managing threads to control user threads.

No user mode/kernel mode switching is required, the speed is fast, and the operating system kernel does not know the existence of multi-threading, so a thread blocking will block the entire process (including all its threads). Programs implemented using user threads are generally more complex. Java has used it before, but finally gave up.

Advantages :

Switching is controlled by the user mode program itself, which does not require kernel intervention, and reduces the consumption of entering and leaving the kernel mode.

Disadvantages :

It is difficult for multi-core processors to map threads to other processors, and single thread blocking will cause the process to block.

 

 

User thread plus lightweight process hybrid implementation

In this hybrid mode, there are both user threads and lightweight processes. User threads are still completely built in user space, so the creation, switching, and destruction of user threads are still cheap and can support large-scale user thread concurrency.

The lightweight process supported by the operating system acts as a bridge between user threads and kernel threads. The system calls of user threads must be completed through lightweight threads, which greatly reduces the risk of process blocking. The ratio of user threads and lightweight processes is an N:M many-to-pair relationship.

Java was implemented based on user threads before jdk 1.2. After 1.2, it was implemented based on the native threading model of the operating system, which is different on each platform. For example, under windows and linux, it is implemented by one-to-one threading model. , On the Solaris platform, it is implemented by one-to-one or many-to-many (solaris supports both one-to-one and many-to-many).

 

thread scheduling

Thread scheduling mainly refers to the process by which the system allocates processor usage rights to threads, and is mainly divided into: cooperative thread scheduling and preemptive thread scheduling.

 

collaborative scheduling

In cooperative scheduling, the execution time of the thread is controlled by the thread itself. After the thread completes its own work, it actively informs the system to switch to another thread. This is how lua's "co-process" is implemented.

advantage:

The implementation is simple. The thread switches the thread after finishing its own work, and the switching operation is known to the thread itself. No sync issues

 

Disadvantages :

The execution time of the thread is uncontrollable. If a thread is blocked due to a problem, the program will be blocked.

 

 

Preemptive thread scheduling

In preemptive thread scheduling, the execution time of each thread is allocated by the system, and the switching of threads is not determined by the thread itself.

advantage:

The execution time of the thread is controllable, and there is no single thread blocking that causes the entire process to block.

 

Java uses preemptive thread scheduling. In addition, Java can also suggest that the system allocate more time to certain threads by setting priorities for threads, but it is not very reliable. The scheduling of threads ultimately depends on the operating system.

 

state transition

 

Java defines 5 thread states. At any point in time, a thread has one and only one of these states. Switch as shown below:

(Picture from: https://my.oschina.net/mingdongcheng/blog/139263)

 

From the above, we know that java threads are mapped to the kernel threads of the operating system. If a thread is blocked or woken up, the operating system needs to help to complete it. This requires switching from user mode to kernel mode. This step of state transition consumes a lot of processor time and needs to be used with caution. How to use it carefully and whether there is room for optimization will be explained in the next article.

In the next article, we will talk about the memory model of threads.

 

-----------------------------------------------------------------------------

If you want to see more interesting and original technical articles, scan and follow the official account.

Focus on personal growth and game development, and promote the growth and progress of the domestic game community.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324642333&siteId=291194637