Java programming – multi-threading/multi-threading construction/multi-threading properties/thread interruption/thread status/thread waiting

Foreword

Sail against the current, if you don’t advance, you will retreat! ! !

Processes and threads

What is a process?

Answer: A process is the smallest unit for the operating system to allocate resources. It is an instance of a running program, or a dynamic execution of an application. For example, when you open a software, such as a browser, on your computer, the operating system creates a new process for the software. During this process, the browser will obtain system resources such as CPU time and memory to perform its functions. Each process has an independent memory unit, which means that each process is independent of each other and does not interfere with each other. To explain with an example in life, the process is like when you go to the bank to transfer money, you are a process to the bank. The bank provides you with resources such as receptionists, transfer personnel, and bank computers to complete the entire service process of transfer for you. The bank’s services to others do not interfere with you.

What is a process control block?

Answer: The process control block (PCB) is a key data structure in the operating system, mainly used to describe and control processes. It contains the necessary data to identify process information, such as process identifier, process status, program counter, registers, memory allocation, open file list, and process priority. Each process has a unique process control block, which is the unique identifier of the process. The operating system uses this control block to find the process and manage and schedule it. For example, when you need to suspend the current process and switch to another process, you need to save the context information of the current process, including CPU registers, program counter, stack pointer, etc., and this information is stored in the PCB. Therefore, PCB is the basis for the operating system to specifically identify and control the process, and it is also a reflection of the centralized characteristics of the process.

What is a thread?

Answer: A thread is an execution unit within a process, which is responsible for executing programs in the process. There is at least one thread in a process. Of course, a process can also have multiple threads. Such a program is also called a multi-threaded program. Threads have their own process control block (PCB), but they do not have an independent address space, but share the same address space with the process to which they belong. This means that each thread can directly access the shared data within the process when exchanging data, which greatly improves the efficiency of data access.

To give an example in life, you are preparing a sumptuous dinner. All aspects of cooking, chopping, washing vegetables, etc. can be regarded as threads, which together constitute the process of preparing dinner. Among them, data exchange may be required between the two threads of cutting vegetables and cooking vegetables. Since they are in the same process, this data exchange is very fast and efficient.

What is the difference between process and thread?

answer:

1. Process is the basic unit for computer system to allocate resources; thread is the basic unit for computer system scheduling and dispatch.

2. The process is a dynamic concept. Each process has its own address space and system resources; a thread is an execution unit in the process and an entity in the process. The thread itself does not own system resources, only one point in operation. Essential resources (such as program counter, registers, and stack);

3. Processes are independent of each other and do not interfere with each other; threads can share all resources owned by the process with other threads belonging to the same process, including the heap and method area resources of the process.

4. Switching between processes requires large time and space overhead: Space overhead is mainly due to the saving and restoration of context information. Since each process has its own independent address space, when switching between processes, it is necessary to save and restore Recover a large amount of context information, including program counters, registers, and memory maps. Time overhead cannot be ignored either. Switching between processes involves saving and restoring the CPU state, which takes a certain amount of time. For example, in a single-core system, if you need to switch between process A and process B, you first need to save the CPU state to the context of process A, and then load the context of process B into the CPU.

In contrast, switching between threads is relatively lightweight. Because multiple threads within the same process share the same address space, thread switching only needs to save and restore a small amount of context information, such as PC pointers and register values. In addition, the creation of a thread is much simpler than that of a process. You only need to determine the values of the PC pointer and register, and allocate a stack to the thread for executing the program. This is also one of the reasons why multi-threading is widely used. It can effectively improve the concurrency and performance of the system.

What is multithreading?

Answer: Multi-threading refers to running multiple threads at the same time in a program to complete different tasks to improve the efficiency and performance of the program. A thread is an execution unit in a process. It is an execution flow within a process and is also the smallest unit of program execution. There is at least one thread in a process. Of course, a process can also have multiple threads. Such a program is also called a multi-threaded program. Multi-threading technology allows the program to handle multiple tasks at the same time, thereby improving the efficiency and response speed of the program. In an application, if you want to schedule threads, the most direct way is to set the priority of the thread. Threads with higher priority have a greater chance of getting CPU execution, while threads with lower priority have a greater chance of getting CPU execution.

Creation of threads

1. Inherit Thread and override the run() method;

class MyThread extends Thread {

    // Override the run() method
    @Override
    public void run() {
        while(true) {
            System.out.println("hello world");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class ThreadDemo1 {
    public static void main(String[] args) {
        Thread t = new MyThread();
        t.start();
        //t.run();

        while(true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

2. Implement the Runnable interface

//The function of Runnable is to express a "task to be executed", and the run method is the details of executing the task.
class MyRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println("hello thread");
    }
}

public class ThreadDemo1 {
    public static void main(String[] args) {
        //This just describes a task
        Runnable runnable = new MyRunnable();
        //Then hand the task to the thread for execution
        Thread t = new Thread(runnable);
        t.start();

        This way of writing is decoupling, and its purpose is to separate threads from the work they are supposed to do.
        If you need this code in the future, you don't need to use multiple threads. Use multiple processes, or this thread pool, or coroutines... At this time, the code changes will be relatively small.
        */
    }

}

3. Use anonymous inner classes and inherit Thread

public class ThreadDemo3 {
    public static void main(String[] args) {
// Create a subclass of Thread (the subclass has no name), create the strength of the subclass, and let the t reference point to the instance
        Thread t = new Thread() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        };
        t.start();
    }
}

4. Use anonymous inner classes to implement Runnable;

public class ThreadDemo4 {
    public static void main(String[] args) {
// This writing method is essentially the same as using an anonymous inner class to inherit Thread.
//It's just that the task of implementing Runnable is handed over to the syntax of the anonymous inner class

// Here a class is created to implement Runnable, an instance of the class is created, and passed to the Thread constructor.
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hell0");
            }
        });
        t.start();
    }
}

5. Implement using lambda expressions

public class ThreadDemo5 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            System.out.println("hello");
        });
        t.start();
    }
}
Thread properties
Attributes Getting method
ID getId()
Name getName()
State getState()
Whether the background thread isDaemon()
Whether it is alive isAlive()
Whether it was interrupted isInterrupted()
getId () method: the getId() method returns the unique identifier of the thread,
getName () method: This method can return the name of the current thread. is not the name of a reference to this thread.
IsDaemon () method: Returns whether the current thread is a background thread. The isDaemon daemon thread is the background thread, and the thread that is switched to the background is the background thread
Thread interruption

Interrupting a thread means: not to stop the thread immediately, but to notify the thread that you should stop. Whether it really stops depends on the specific code writing of the thread.

1 , use a flag bit to control whether the thread terminates.

2 , use the flag bit that comes with Thread to make a judgment,

Why does sleep need to clear the flag?

Answer: After waking up, the choice is left to the programmer whether the thread should be terminated or not, whether it should be terminated immediately or later.

Thread status

1. NEW created the Thread object, but start has not been called yet (the corresponding PCB has not been created in the kernel);

2. TERMINATED means that the PCB in the kernel has been executed (the PCB has been released), but the Thread object is still there.

3. RUNNABLE runnable threads include the following two types:

a) Threads being executed on the CPU.

b) In the ready queue, you can execute it on the CPU at any time

4. WAITING

5, TIMED_WAITING

6, BLOCKED

4, 5, and 6 are all blocked, indicating that the thread PCB is in the blocking queue. Only the reasons for the obstruction are different.

Thread waiting

Sometimes, we need to wait for a thread to complete its work before proceeding to the next step. This is what thread waits are for.

Method Description
public void join() Wait for the thread to end
public void join(long millis) Wait for the thread to end, up to millis milliseconds
public void join(long millis, int nanos) Same principle, but with higher precision

When join() has no parameters, it just waits to death. The join method with parameters specifies a maximum waiting time.

Note: If the t thread has ended when the main thread calls t.join(), join will not block and will return immediately.

I am Brother Squidward who focuses on studying~