Creation and status of multithreading

Posted by Stopofeger on Fri, 28 Jan 2022 15:58:06 +0100

Multithreading

Multi task execution

If there is no multitasking, multithreading is not required

program

Java source Program and bytecode file are called "Program", which is a static concept.

process

The program in execution is called process, which is a dynamic concept. In order for the computer program to run, the computer needs to load both code and data.

thread

Thread is the smallest unit that the operating system can schedule operations.
It is included in the process and is the actual operation unit in the process.
A thread refers to a single sequential control flow in a process. Multiple threads can be concurrent in a process, and each thread executes different tasks in parallel.

The difference between process and thread

differenceprocessthread
Fundamental differenceUnit of resource allocationScheduling execution unit
expensesEach process has its own code and data space, and the switching between processes will have a large overheadThreads can be regarded as lightweight processes. The same kind of threads share code and data space. Each thread has an independent program counter (PC), and the overhead of thread switching is small
EnvironmentMultiple tasks can be run simultaneously in the operating systemMultiple sequential streams are executed simultaneously in the same application
Allocate memoryWhen the system is running, it will allocate different memory areas for each processAll resources of the process are shared among threads, and each thread only has its own stack and local variables. Threads are independently scheduled and executed by the CPU. In a multi CPU environment, multiple threads are allowed to run at the same time
Inclusion relationA process without threads can be regarded as a single thread. If a process has multiple threads, the execution process is not one line, but multiple lines (threads) work togetherThreads are part of a process, so threads are sometimes referred to as lightweight processes or lightweight processes

The goal of learning multithreading

1. Create and enable multithreading (key)

2. Thread state

3. Thread safety (key)

3. Thread communication

Create and enable multithreading

1 inherit Thread class

Create an instance of the Thread subclass and override the run method, which will be executed automatically after calling the start() method

1) Create Thread class: inherit Thread class + override run() method

2) Construct thread class object: an object that creates a subclass

3) Start thread: call the start() method through a subclass object

//1) Create thread class
public class Thread01 extends Thread{
    //Override run() to define the thread body
    @Override
    public void run() {
        for(int i = 1;i<=20;i++){
            System.out.println("Hee hee...");
             try {
                 Thread.sleep(2);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
        }
    }
    public static void main(String[] args) {
        //2) Construct thread class object
        Thread01 t01 = new Thread01();
        //3) Start thread
        t01.start();
        for(int i = 1;i<=20;i++){
            System.out.println("ha-ha...");
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

be careful:

Inherit parent class - > single inheritance

The run method cannot throw exceptions, but can only catch exceptions

The run method has no return value

Thread.sleep(): the specified number of milliseconds to sleep (temporarily stop execution) the currently executing thread

2. Implement Runnable interface (recommended)

1) Create the implementation class of Runnable interface + rewrite the run() method

2) Create an implementation class object

3) Create Thread class object with implementation class object

4) Start thread

advantage:

Simple, multiple interfaces can be implemented to realize resource sharing

//1) Create the implementation class of Runnable interface + rewrite the run() method
public class Thread02 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i <20; i++) {
            System.out.println("Hee hee!!!!!");
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args){
        //2) Create an implementation class object
        Thread02 t02 = new Thread02();
        //3) Create Thread class object with implementation class object
        Thread th = new Thread(t02);
        //4) Start thread
        th.start();
        for (int i = 0; i <20; i++) {
            System.out.println("Hip Hop!!");
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Define the thread body through internal classes

public class Thread02 {
    //1) Create the implementation class of Runnable interface + rewrite the run() method
    static class Inner1 implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                System.out.println("Haha!!!!");
                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        //Method 1: use local inner classes
        class Inner2 implements Runnable{
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println("Hip Hop!!");
                    try {
                        Thread.sleep(2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
		//Create and start threads
        new Thread(new Inner1()).start();
        new Thread(new Inner2()).start();

        //Method 2: optimize local inner classes with anonymous inner classes
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 30; i++) {
                    System.out.println("Hip Hop!!!!");
                    try {
                        Thread.sleep(5);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        //Method 3: optimize anonymous inner classes using Lambda
        new Thread(()->{
            for (int i = 0; i < 30; i++) {
                System.out.println("Hip Hop!!!!");
                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

3. Callable interface (understand)

Create an implementation class that implements the Callable interface + rewrite the call() method

Callable interface under juc (java.util.concurrent) package

Advantages: exceptions can be thrown and return values can be defined

Disadvantages: complex use

public class Thread03 implements Callable<String> {

    @Override
    public String call() throws Exception {
        for (int i = 0; i < 20; i++) {
            System.out.println("Hee hee!!!!");
            Thread.sleep(10);
        }
        return null;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //1. Create thread
        Thread03 t = new Thread03();
        //2.1) create execution service
        ExecutorService es = Executors.newCachedThreadPool();
        //2) Submit for execution
        Future<String> f = es.submit(t);
        for (int i = 0; i < 20; i++) {
            System.out.println("Hip hop!!");
            Thread.sleep(3);
        }
        //3) Get execution results
        System.out.println(f.get());
    }
}

Similarities and differences of the three methods:

Thread: inheritance method, not recommended, because Java inherits by itself. If you inherit thread, you can't inherit other classes. It's not flexible enough

Runnable: implements the interface, which is more flexible than the Thread class and has no single inheritance restrictions. It is recommended

Callable: both Thread and Runnable are overridden run() methods with no return value. Callable is overridden call() method with return value

Thread pool

Thread pool is to create some threads first, and their collection is called thread pool

Using thread pool can improve performance very well. When the system starts, the thread pool creates a large number of idle threads. The program passes a task to the thread pool, and the thread pool will start a thread to execute the task. After execution, the thread will not die, but return to the thread pool to become idle again and wait for the execution of the next task.

Working mechanism of thread pool

In the programming mode of thread pool, the task is submitted to the whole thread pool rather than directly to a thread. After getting the task, the thread pool will look for whether there are idle threads internally. If so, the task will be handed over to an idle thread. A thread can only execute one task at the same time, but it can submit multiple tasks to a thread pool at the same time.

Status of the thread

1 newborn state

new Thread(): a new thread enters a new state

2 ready status

start(): a thread will enter the ready state, enter the ready queue and wait for cpu scheduling

3 operation status

When a cpu call is dispatched to a thread in the ready queue, the thread begins to enter the running state

4 blocking state

The thread cannot execute normally and may enter a blocking state

5 termination status

Thread execution completed

How to enter the ready state

1. start(): start the process

2. Thread switching: the switched thread returns to the ready state and waits for the next call

3. Unblock

4. yield(): yield thread

How to enter the blocking state

1,sleep()

2,join()

3,wait()

4. IO, etc

How to enter the termination state

1. stop() termination method – > is obsolete and is not recommended

2. Judge by adding logo – > recommended

3. Normal execution completed

be careful:

1) Once a thread is executed, it cannot be resumed, and new is also a new thread

2) When the blocking is removed, it cannot be directly restored to the running state. It will be restored to the ready state first and wait for the next CPU scheduling

Topics: Java Programming Multithreading