Java learning phase I - 24 Java-Api05-1 process thread multithreading

Posted by AcousticJames on Sat, 15 Jan 2022 12:08:56 +0100

Process and thread

1 process

1.1 concept of process

A process is a running program, which represents the memory area occupied by the program

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

1.3 parallelism and concurrency

HA(High Availability): in the scenario of high concurrency, ensure the program availability as much as possible and reduce the time when the system cannot provide services

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 extends the concept of multi process, so that the same process can process multiple tasks simultaneously

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

The randomness of threads means that only one program is executing at the same time
On the macro level, we think these programs run at the same time, but in fact, the micro time is because the CPU is switching efficiently, which makes each program run at the same time on the surface, that is, on the macro level, all processes / threads seem to run at the same time, but on the micro level, a CPU can only handle one thing at the same time The switching speed is even nanosecond, very fast

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 the 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:

  1. New: when the thread object is created, it enters the new state For example: Thread t = new MyThread();
  2. 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
  3. 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
  4. 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
  5. 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: thread1 java

package cn.tedu.thread;
/**This class is used to test multithreaded programming mode 1 
 * extends Thread
 * */
public class Thread1 {
	public static void main(String[] args) {
		//4. Create thread object
		MyThread t = new MyThread();/**The corresponding status is the new status*/
		/**If you only call run() of two threads, one thread will be executed first, and then another thread will be executed. There will be no multithreading effect*/
		//t.run();// How to execute the business of run()-- Can we really use run () to execute our multithreaded tasks?
		/**run()Essentially different from start(), run() can only be executed as a single threaded ordinary method executed sequentially, without the effect of multithreading programming*/
		t.start();/**The corresponding state is the ready state. If you want to use multithreading to start work, you must call start() to start the thread*/
		/**6.Only by calling satrt() will the thread change from a new state to a runnable state
		 * When we call start() to start the thread, the underlying virtual opportunity automatically calls the business of run()
		 * */
		//5. To simulate multithreading, you need to start at least two threads. If only one thread is started, it is a single threaded program
		MyThread t2 = new MyThread();
		//t2.run();
		t2.start();
		/**The randomness of threads. The execution results of T0, T1 and T2 are uncontrollable because they are scheduled by the CPU, and the results are random*/
		/**Randomness of threads: the CPU will automatically schedule the threads in the running state, but we can't control which time slice executes which thread*/
//		2=Thread-0
//		3=Thread-0
//		2=Thread-1
//		1=Thread-2
//		3=Thread-1
		MyThread t3 = new MyThread("Small ash");
		t3.start();
	}
}
//1. Custom multithreading class
/**1.Method 1:extends Thread*/
class MyThread extends Thread{
	/**Finally: in order to modify the thread name, the default name assigned by the system is no longer used, and a parameter structure needs to be provided*/
	//Right click -- > source -- > the penultimate -- > Deselect all -- > to select a parameterless construct or a named construct
	public MyThread() {
		super();
	}
	public MyThread(String name) {
		super(name);
	}	
	//2.1 the business in the thread must be written in run()
	/**2.Source code: 745 lines*/
	//    @Override
	//    public void run() {
	//        if (target != null) {
	//            target.run();
	//        }
	//    }
	/**3.If you are not satisfied with the contents of run(), you can override alt+/*/
	//2.2 override run() in Thread parent class
	@Override
	public void run() {
		/**4.super It refers to the reference of the parent class object, that is, the business in Thread class is used by default. It is not required*/
		//super.run();
		//3. Write service: output the name of the currently executing thread 10 times
		for (int i = 0; i < 10; i++) {
			/**5.getName()You can get the name of the thread executing the task. It is a method inherited from the parent class and can be used 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 to test multithreaded programming mode 2 implements Runnable*/
public class Thread2 {
	public static void main(String[] args) {
		//4. Create thread object
		MyRunnable target = new MyRunnable();
		//5.2 question: how to bind the implementation class of the interface to the Thread class
		Thread thread1 = new Thread(target);		
		//5.1 how to start a thread?
		thread1.start();		
		//6. -- to start by multithreading programming, you need to create multiple thread objects and start
		//8. Modify the name of the Thread -- use the parameter structure of the Thread class
		Thread thread2 = new Thread(target,"jack");
		Thread thread3 = new Thread(target,"rose");
		thread2.start();
		thread3.start();		
		//7. Test the difference between start() and run()
		//run() is only the effect of ordinary method execution, that is, the effect of single thread sequential execution. There is no multi-threaded line phenomenon
	}
}
//1. Customize the multithreading class. 2. Implements runnable
class MyRunnable implements Runnable{
	//2. Put the business into run(), and rewrite the in the Runnable interface
	@Override
	public void run() {
		//3. Write the service and print the thread name 10 times
		for(int i = 0; i< 10; i++){
			//Problem: in the Runnable interface, there is no redundant method dimension, only one run()
			//Thread.currentThread() gets the thread object currently executing business. getName() gets the name of this thread object
			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 class implements multi-threaded ticket selling cases by inheriting Thread class*/
public class TestThread {
    public static void main(String[] args) {
        //5. Create multiple thread objects Ctrl+D copy the current line
        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. Custom thread ticketing business class
class TicketThread extends Thread{
    //3. Define variables to save the number of votes
    //int tickets = 100;// No, it will sell 400 tickets
    //7. Solve the BUG that four threads sold 400 tickets
    static int tickets = 100;//Static resources belong to class resources and are shared by all global objects. There is only one copy
    //2. Write the business in the rewrite run()
    @Override
    public void run() {
        //4. Sell tickets all the time through circular structure
        while (true){
            try {
                //8. If the data can withstand the sleep test, it can be said that the data has no potential safety hazard - man-made problems
                //Question 1: resale occurs: the same ticket is sold to multiple people
                //Question 2: oversold: exceeding the specified number of votes, and even selling votes such as 0 and - 1
                Thread.sleep(10);//Let the program sleep for 10ms
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(getName()+"="+tickets--);
            //Make a judgment. If there are no tickets, exit the dead circle
            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 class implements multi-threaded ticketing cases by implementing the Runnable interface*/
public class TestRunnable {
    public static void main(String[] args) {
        //5. Create target business object
        TicketRunnable target = new TicketRunnable();
        //6. Use the parameter structure in the Thread class to bind the target object to the Thread object
        Thread t1 = new Thread(target);
        Thread t2 = new Thread(target);
        Thread t3 = new Thread(target);
        Thread t4 = new Thread(target);
        //7. Start the thread in a multithreaded manner
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}
//1. Create a custom multithreading class
class TicketRunnable implements Runnable{
    //3. Create a member variable to save the number of votes. Note that it must be static
    static int tickets = 100;
    //2. Add unimplemented methods in the interface and put the business in run()
    @Override
    public void run() {
        while (true){
            try {
                //Two problems after hibernating the program:
                //Question 1 Resale: a ticket is sold to more than one person
                //Question 2 Oversold: the number of votes is 0 or even negative
                Thread.sleep(10);//Let the program sleep for 10ms
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //3. Get the name of the thread that is currently selling tickets and the ticket
            System.out.println(Thread.currentThread().getName()+"="+tickets--);
            //4. Set the outlet of the dead cycle
            if (tickets <= 0) break;
        }
    }
}

6.3 problems

  1. 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
  2. Oversold, 0, - 1, - 2.
  3. If resale occurs, the same ticket is sold to multiple people.
  4. How do multithreading security problems arise? The common situation is due to the randomness of threads + access latency.
  5. How to judge whether the program has thread safety problems in the future?
    In multithreaded programs + shared data + multiple statements operate on shared data
    Solution: here is the synchronization lock point in the next section

Topics: Java Multithreading thread api Process