Process and thread
1 process
1.1 concept of process
A process is a running program that occupies the corresponding memory area and is executed and calculated by the CPU.
1.2 process characteristics
Independence
Process is an independent entity in the system. It can have its own independent resources. Each process has its own private address space. Without the permission of the process itself, a user process cannot directly access the address space of other processes
Dynamics
The difference between process and program is that program is only a static instruction set, while process is an instruction set active in the system. After adding the concept of time, the program is called process, which has its own life cycle and various states. These concepts are not possessed by the program
Concurrency
Multiple processes can execute concurrently on a single processor CPU, and multiple processes will not affect each other
2 threads
2.1 thread concept
Thread is the smallest unit that OS can schedule operations. It is included in the process and is the actual operation unit in the process
A process can start multiple threads, one of which calls other threads in the process.
The process switching we see is also the main thread of different processes
Multithreading allows the same process to process multiple tasks simultaneously, which is equivalent to expanding the function of the process.
2.2 relationship between process and thread
An operating system can have multiple processes. A process can contain one thread (single threaded program) or multiple threads (multi-threaded program)
Each thread not only shares the memory of the same process, but also has its own independent memory space
Therefore, if you want to use threading technology, you must first have a process. The process is created by the OS operating system, usually in C or C + +
3 multithreading features
3.1 randomness
We think that multiple processes run at the same time on the macro level, but on the micro level, a CPU [single core] can only execute one thread in a process.
So why does it look like multiple processes are executing at the same time?
This is because the CPU switches efficiently at the nanosecond level or even faster, which exceeds people's reaction speed, which makes each process seem to be running at the same time. In other words, on the macro level, all processes seem to be parallel [running at the same time], but on the micro level, they are serial [one CPU can only process one thing at a time].
Serial and parallel
Serial means that a CPU can only process one thing at a time, similar to a single lane
Parallel means that multiple CPU s can handle multiple things at the same time, similar to multi lane
3.2 CPU time-sharing scheduling
Time slice, that is, a time period allocated by the CPU to each thread, is called its time slice, that is, the time that the thread is allowed to run. If the thread is still executing when the time slice is used up, the CPU will be deprived and allocated to another thread to suspend the current thread. If the thread blocks or ends before the time slice is used up, the CPU will switch immediately to avoid waste of CPU resources, When you switch to the previously suspended thread again, restore the scene and continue execution.
Note: we cannot control which threads the OS chooses to execute. The underlying OS has its own rules, such as:
1.FCFS(First Come First Service algorithm)
2.SJS(Short Job Service short service algorithm)
3.3 thread status
Due to the complexity of thread states, we first learn the three basic thread states and their transitions, referred to as the "three state model":
Ready (runnable) status: the thread is ready to run and can be executed immediately as long as it obtains the CPU
Execution (running) state: the state in which the thread has obtained the CPU and its program is running
Blocking state: the state in which the running thread is temporarily unable to execute due to some events (I/O requests, etc.), that is, thread execution blocking
Ready → execute: allocate CPU for the ready thread to change to the execution state“
Execute → ready: the executing thread is deprived of the CPU to suspend execution due to the running out of time slices, and becomes ready
Execute → block: if the executing thread is blocked and cannot be executed due to an event, it will change from execution to blocking
(for example, a thread is accessing a critical resource while the resource is being accessed by another thread)
On the contrary, if the previously required resources are obtained, it changes from blocking to ready state and waits for the allocated CPU to execute again
We can add two more states:
- Creation status: the creation of a thread is complex. You need to apply for a PCB first, then allocate necessary resources for the thread to run, and turn the thread into ready status and insert it into the ready queue
- Termination status: wait for the OS to deal with the aftermath, and finally clear the PCB and return the PCB to the system
PCB(Process Control Block): in order to ensure that each thread participating in concurrent execution can run independently, the OS is configured with a unique data structure PCB to describe the basic situation and activity process of threads, so as to control and manage threads
3.4 thread status and code comparison
Thread life cycle has five main states:
New: when the thread object is created, it enters the new state For example: Thread t = new MyThread();
Runnable: when the start() method of the thread object is called, the thread enters the ready state
A thread in the ready (runnable) state only indicates that the thread is ready to wait for the CPU to schedule execution at any time. It does not mean that the thread will execute immediately after t.start() is executed
Running: when the CPU schedules a thread in the ready state, this thread is the real execution, that is, it enters the running state
The ready state is the only entry into the running state, that is, if a thread wants to enter the running state for execution, it must be in the ready state first
Blocked: a thread in the running state temporarily gives up the right to use the CPU and stops execution for some reason. At this time, it enters the blocked state and has no chance to be selected by the CPU for execution again until it enters the ready state
According to different causes of blocking States, blocking states can be subdivided into three types:
Wait blocking: the thread in the running state executes the wait() method, and the thread enters the wait blocking state
Synchronization blocking: if a thread fails to acquire a synchronized synchronization lock (because the lock is occupied by other threads), it will enter the synchronization blocking state
Other blocking: when calling the thread's sleep () or join () or issuing an I/O request, the thread will enter the blocking state When sleep() status times out join() waits for the thread to terminate or time out, or the thread to return to the ready state when I/O processing is completed
Dead: when the thread has finished executing or exited the run() method due to an exception, the thread ends its life cycle
4. Multithreaded code creation method 1: inherit Thread
4.1 General
The Thread class is essentially an instance that implements the Runnable interface and represents an instance of a Thread
The only way to start a Thread is through the start() instance method of the Thread class
The start() method is a native method that notifies the underlying operating system that Finally, the operating system starts a new thread, and the operating system will execute run()
Multithreading implemented in this way is very simple. You can automatically start a new thread and execute your own defined run() method by directly extending thread through your own class and overriding the run() method
Simulate opening multiple threads, and each thread calls the run() method
4.2 common methods
Construction method
Thread() assigns a new thread object
Thread(String name) assigns a new thread object
Thread(Runnable target) assigns a new thread object
Thread(Runnable target,String name) assigns a new thread object
Common method
static Thread currentThread( )
Returns a reference to the thread object currently executing
long getId()
Returns the identity of the thread
String getName()
Returns the name of the thread
void run()
If the thread is constructed with a separate Runnable running object, the run method of the Runnable object is called
static void sleep(long millions)
Hibernates (pauses) the currently executing thread for a specified number of milliseconds
void start()
Start the thread: the Java virtual machine calls the thread's run()
4.3 test the creation method of multithread 1
Create package: CN tedu. thread
Create class: testthread1 java
package cn.tedu.thread; /*This class is used for multithreading programming implementation scheme 1: inherit the Thread class to complete*/ public class TestThread1 { public static void main(String[] args) { //4. Create a thread object for testing /*4.new This corresponds to the new state of the thread * 5.To simulate multithreading, you must start at least two threads. If you only start one, it is a single threaded program*/ MyThread t1 = new MyThread(); MyThread t2 = new MyThread(); MyThread t3 = new MyThread(); MyThread t4 = new MyThread(); /*6.If this run() is called directly, there will be no effect of multithreading preemption * Just regard these two sentences as the call of ordinary methods. Whoever writes first will execute first*/ //t1.run(); //t2.run(); /*7.start()The corresponding state is the ready state, which will add the newly created thread to the ready queue * As for when to execute, it is the effect of multi-threaded execution. You need to wait for the OS to select and allocate CPU * 8.When executing, the bottom layer of start() will automatically call the run() business we rewrite * 9.The execution of threads is random, that is, how t1-t4 is executed * Depending on the CPU scheduling and time slice allocation, we can't decide*/ t1.start();//Start thread 1 in a multithreaded manner to turn the current thread into a ready state t2.start();//Start thread 2 in a multithreaded manner to turn the current thread into a ready state t3.start();//Start thread 3 in a multithreaded manner to turn the current thread into a ready state t4.start();//Start thread 4 in a multithreaded manner to turn the current thread into a ready state } } //1. Customize a multithreading class, and then let this class inherit Thread class MyThread extends Thread{ /*1.Scheme 1 of multithreading programming: it is completed by inheriting Thread class and overriding run() */ //2. Rewrite run (). Run () contains our own business @Override public void run() { /*2.super.run()It refers to the business of calling the parent class. Now we want to use our own business, so comment it out*/ //super.run(); //3. Complete the business: print the name of the thread currently executing 10 times for (int i = 0; i < 10; i++) { /*3.getName()Indicates that you can get the name of the thread currently executing * Since this class inherits the Thread class, you can use this method directly*/ System.out.println(i+"="+getName()); } } }
5 multi thread code creation method 2: implement Runnable interface
5.1 general
If your own class already extends another class, you cannot inherit more. At this time, you can implement a Runnable interface
5.2 common methods
When void run() creates a thread using the object that implements the interface Runnable, it will cause the run() method to call the object in the thread that is executed independently.
5.3 exercise 2: test how multithreading is created 2
Create package: CN tedu. thread
Create class: thread2 java
package cn.tedu.thread; /*This class is used for multithreading programming implementation scheme 2: it is completed by implementing the Runnable interface*/ public class TestThread2 { public static void main(String[] args) { //5. Create custom class object -- target business class object MyRunnable target = new MyRunnable(); //6. How to start a Thread? You don't have one. You need to establish a relationship with Thread Thread t1 = new Thread(target); Thread t2 = new Thread(target); Thread t3 = new Thread(target); Thread t4 = new Thread(target); t1.start(); t2.start(); t3.start(); t4.start(); } } //1. Custom multithreading class class MyRunnable implements Runnable{ //2. Add the abstract method run() in the parent interface, which contains its own business @Override public void run() { //3. Write the service and print the name of the currently executing thread 10 times for (int i = 0; i < 10; i++) { /*Problem: neither the custom class nor the parent interface Runnable has a method to get the name * Therefore, you also need to find from the Thread: * currentThread():Static method to get the thread object currently executing * getName():Gets the name of the current thread*/ System.out.println(i+"="+Thread.currentThread().getName()); } } }
5.4 comparison of two implementation methods
Inherit Thread class
Advantages: it is easy to write. If you need to access the current thread, you don't need to use thread The currentthread() method can directly use this to obtain the current thread
Disadvantages: the custom Thread class has inherited the Thread class, so other classes cannot be inherited later
Implement Runnable interface
Advantages: the custom thread class only implements the Runnable interface or Callable interface, and can inherit other classes later. In this way, multiple threads can share the same target object, so it is very suitable for multiple threads to process the same resource, so that the CPU, code and data can be separated (decoupled) to form a clear model, It better embodies the idea of object-oriented
Disadvantages: programming is slightly complex. If you want to access the current thread, you need to use thread Currentthread() method
6 ticketing cases
Demand: four ticket windows are designed, with a total of 100 tickets. Use multithreaded programming and write code
6.1 scenario 1: inherit Thread
Create package: CN tedu. tickets
Create class: testthread java
package cn.tedu.tickets; /*Requirements: design a multi-threaded programming model, and sell 100 tickets in total in 4 windows * This scheme uses multithreading programming scheme 1 to inherit the Thread class*/ public class TestThread { public static void main(String[] args) { //5. Create multiple thread objects TicketThread t1 = new TicketThread(); TicketThread t2 = new TicketThread(); TicketThread t3 = new TicketThread(); TicketThread t4 = new TicketThread(); //6. Start in a multithreaded manner t1.start(); t2.start(); t3.start(); t4.start(); } } //1. Customize multi-threaded ticketing class and inherit Thread class TicketThread extends Thread{ //3. Define variables to save the number of votes to be sold /*Problem: a total of 400 tickets were sold for the four thread objects. The reason is that the objects were created four times and their member variables were operated respectively * Solution: let all objects share the same data, and the number of votes needs to be set to static*/ static int tickets = 100; //2. Rewrite the run() of the parent class, which is our business @Override public void run() { //4.1 circulation ticket selling while(true){ try { //7. Let each thread go through sleep and increase the frequency of thread state switching and the probability of error //Question 1: resale occurs: multiple people sell the same ticket //Question 2: oversold occurred: the specified number of votes exceeded 100, and there were 0 - 1 - 2 tickets Thread.sleep(10);//Let the current thread sleep for 10ms } catch (InterruptedException e) { e.printStackTrace(); } //4.2 print the name of the thread currently selling tickets, and the number of votes is - 1 System.out.println(getName()+"="+tickets--); //4.3 make judgment. If there is no ticket, exit the dead cycle if(tickets <= 0) break;//Note that the outlet must be set for the dead cycle } } }
6.2 scheme 2: realize Runnable
Create package: CN tedu. tickets
Create class: testrunnable java
package cn.tedu.tickets; /*Requirements: design a multi-threaded programming model, and sell 100 tickets in total in 4 windows * This scheme uses multithreading programming scheme 2 to implement the Runnable interface*/ public class TestRunnable { public static void main(String[] args) { //5. Create the implementation class object of Runnable interface as the target business object TicketRunnable target = new TicketRunnable(); //6. Create multiple thread class Thread objects and hand over the target business object to multiple thread objects for processing Thread t1 = new Thread(target); Thread t2 = new Thread(target); Thread t3 = new Thread(target); Thread t4 = new Thread(target); //7. Start multiple threaded objects in a multithreaded manner t1.start(); t2.start(); t3.start(); t4.start(); } } //1. Customize the multithreading class to implement the Runnable interface class TicketRunnable implements Runnable{ //3. Define a member variable to save 100 votes /*Since the custom class object is created only once, the votes are shared by all Thread objects and Thread class objects*/ int tickets = 100; //2. Add the methods that are not implemented in the interface. The methods are our business @Override public void run() { //4.1 circulation ticket selling while(true){ //8. Let the thread sleep for 10ms to increase the probability of thread state switching and error try { Thread.sleep(10);//Let the current thread sleep for 10ms } catch (InterruptedException e) { e.printStackTrace(); } //4.2 print the name of the thread currently selling tickets & number of tickets - 1 System.out.println(Thread.currentThread().getName()+"="+tickets--); //4.3 set the exit of dead circulation and stop selling tickets when there are no tickets if(tickets <=0 ) break; } } }
6.3 problems
Every time you create a thread object, you will generate a tickets variable with the value of 100. After creating the object four times, 400 tickets will be generated. Do not meet the needs, how to solve it? Whether the tickets variable can be shared among each object ensures that how many objects sell these 100 tickets.
Solution: use static decoration
Oversold, 0, - 1, - 2.
If resale occurs, the same ticket is sold to multiple people.
How do multithreading security problems arise? The common situation is due to the randomness of threads + access latency.
How to judge whether the program has thread safety problems in the future?
In multithreaded programs + shared data + multiple statements operate on shared data