Dark horse programmer full set of Java tutorials_ Java basics tutorial_ Implementation of multithreading multithreading

1.1 process: it is a running program

  • It is an independent unit for system resource allocation and call;
  • Each process has its own memory space and system resources.

1.2 thread: it is a single sequential control flow that is often summarized by people and you. It is an execution path

  • Single thread: if a process has only one execution path, it is called a single thread program;
  • Multithreading: if a process has multiple execution paths, it is called a multithreaded program;
  • If setting and editing text attributes in Notepad cannot be performed simultaneously, this is a single thread; In mine sweeping, timing and game can be carried out at the same time, which is multi-threaded.

1.3 implementation mode of multithreading 1

  • Method 1: inherit Thread class
    (1) Define a class MyThread, which inherits the Thread class;
    (2) Override the run() method in the MyThread class;
    (3) Create an object of MyThread class;
    (4) Start the thread.
  • Why override run()?
    Because run () is used to encapsulate the code formed and executed. (there may be other codes in the MyThread class, but not all codes need to be executed by threads. In order to distinguish which codes can be executed by threads, Java provides run() to encapsulate the code executed by threads.)
  • What is the difference between the run() and start() methods?
    (1) run(): encapsulates the code executed by the thread and calls it directly, which is equivalent to calling ordinary methods;
    (2) start(): starts the thread, and then the JVM calls the run() method of the thread.
public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(i);
        }
    }
}
    public static void main(String[] args) {
        MyThread my1 = new MyThread();
        MyThread my2 = new MyThread();

        //my1.run();
        //my2.run();

        my1.start();
        my2.start();
    }

1.4 setting and obtaining thread name

  • We have implemented the multithreaded program and output the data on the console, but we don't know which Thread the data is from, so we need to learn to set and obtain the Thread name. To do this, the Thread class provides two methods:
    (1) void setName(String name): change the name of this thread to name;
    (2) String getName(): returns the name of this thread;
    (3) The thread name can also be set through the construction method.
  • Get the thread name where main() is located: public static Thread currentThread(), get the reference to the currently executing thread object.
public class MyThread extends Thread {
    public MyThread() {
    }

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + ":  " + i);
        }
    }
}
/*
Thread Source code analysis of class parameterless construction method:
public Thread() {
    init(null, null, "Thread-" + nextThreadNum(), 0);
}
1,nextThreadNum() of parameterless constructor method call
private static int threadInitNumber;//Not initialized. The default value is 0,1,2
private static synchronized int nextThreadNum() {
    return threadInitNumber++;//0,1...
}
2,init(ThreadGroup g, Runnable target, String name,long stackSize) of parameterless construction method call
//The parameterless constructor passed "Thread-" + nextThreadNum() to String name
private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize) {
    init(g, target, name, stackSize, null, true);
}
2.1  init(ThreadGroup...)Private void init called (ThreadGroup g, runnable target, string name, long stacksize, accesscontrolcontext ACC, Boolean inheritthreadlocals)
//init(ThreadGroup...)Passed String name to String name, and assigned name to the member variable name
private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize, AccessControlContext acc,
                  boolean inheritThreadLocals) {
    ...
    this.name = name;
    ...
}
2.1.1  name Statement of
private volatile String name;
 */
    public static void main(String[] args) {
        //There are three ways to set and get thread names
        //Mode 1
        //MyThread my1 = new MyThread();
        //MyThread my2 = new MyThread();
        //my1.setName("high speed rail");
        //my2.setName("aircraft");

        //Mode 2
        //Thread(String name) belongs to the parent class thread. We can't call this method directly. We need to write our own construction method with parameters
        //MyThread my1 = new MyThread("high speed rail");
        //MyThread my2 = new MyThread("aircraft");

        //my1.start();
        //my2.start();

        //Mode 3
        //static Thread currentThread() returns the application of the thread object currently executing
        System.out.println(Thread.currentThread().getName());
    }

1.5 thread scheduling

  • Threads have two scheduling models:
    (1) Time sharing scheduling model: all threads use the right to use CPU in turn, and evenly allocate the time slice of CPU occupied by each thread;
    (2) Preemptive scheduling model: give priority to the threads with high priority to use CPU. If the threads have the same priority, they will randomly select one. The threads with high priority will obtain more CPU time slices;
    (3) Java uses a preemptive scheduling model.
  • Randomness of multithreaded program execution: if there is only one CPU, then the CPU can only execute one instruction at a certain time. Only when the thread gets the CPU time slice, that is, the right to use, can it execute instructions. Therefore, the execution of multithreaded programs is random, because it is not certain who grabs the right to use the CPU.
  • Methods for setting and obtaining Thread priority in Thread class:
    (1) public final int getPriority(): returns the priority of this thread;
    (2) public final void setPriority(int newPriority): change the priority of this thread.
    (3) The default thread priority is 5, and the thread priority range is 1 ~ 10. High thread priority only means that the thread has a high probability of obtaining CPU time slice, but you can see the effect you want when it runs more times or more times.
public class MyThread extends Thread {
    public MyThread() {
    }

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + ":  " + i);
        }
    }
}
    public static void main(String[] args) {
        MyThread my1 = new MyThread("high-speed rail");
        MyThread my2 = new MyThread("aircraft");
        MyThread my3 = new MyThread("automobile");

        //System.out.println(my1.getPriority());//5
        //System.out.println(my2.getPriority());//5
        //System.out.println(my3.getPriority());//5

        //my1.setPriority(1000);//IllegalArgumentException: illegal parameter exception
        System.out.println(Thread.MAX_PRIORITY);//10
        System.out.println(Thread.MIN_PRIORITY);//1
        System.out.println(Thread.NORM_PRIORITY);//5

        my1.setPriority(5);
        my2.setPriority(7);
        my3.setPriority(3);

        my1.start();
        my2.start();
        my3.start();
    }

1.6 thread control

Method nameexplain
static void sleep(long millis)Causes the currently executing thread to stay (pause execution) for the specified number of milliseconds
void join()Wait for this thread to die
void setDeamon(boolean on)Mark this thread as a daemon thread. When all running threads are daemon threads, the Java virtual machine will exit
public class ThreadSleep extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++){
            System.out.println(getName() + ": " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
    public static void main(String[] args) {
        ThreadSleep ts1 = new ThreadSleep();
        ThreadSleep ts2 = new ThreadSleep();
        ThreadSleep ts3 = new ThreadSleep();

        ts1.setName("Cao Cao");
        ts2.setName("Liu Bei");
        ts3.setName("Sun Quan");

        ts1.start();
        ts2.start();
        ts3.start();
    }
public class ThreadJoin extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++){
            System.out.println(getName() + ": " + i);
        }
    }
}
    public static void main(String[] args) {
        ThreadJoin tj1 = new ThreadJoin();
        ThreadJoin tj2 = new ThreadJoin();
        ThreadJoin tj3 = new ThreadJoin();

        tj1.setName("Kangxi");
        tj2.setName("Four elder brother");
        tj3.setName("Eight elder brother");

        tj1.start();
        try {
            tj1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        tj2.start();
        tj3.start();
    }
public class ThreadDeamon extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++){
            System.out.println(getName() + ": " + i);
        }
    }
}
    public static void main(String[] args) {
        ThreadDeamon td1 = new ThreadDeamon();
        ThreadDeamon td2 = new ThreadDeamon();

        td1.setName("Guan Yu");
        td2.setName("Fei Zhang");

        //Set the main thread to Liu Bei
        Thread.currentThread().setName("Liu Bei");

        //Set daemon thread
        td1.setDaemon(true);
        td2.setDaemon(true);

        td1.start();
        td2.start();

        for (int i = 0; i < 10; i++){
            System.out.println(Thread.currentThread().getName() + ": " + i);
        }
    }

1.7 thread life cycle

1.8 implementation mode of multithreading 2

  • There are two implementations of multithreading:
    (1) Inherit Thread class;
    (2) Implement the Runable interface.
  • Implement the Runable interface:
    (1) Define a class MyRunable to implement the Runable interface;
    (2) Override run() in the MyRunable class;
    (3) Create an object of MyRunable class;
    (4) Create the object of Thread class and take the MyRunable object as the parameter of the construction method;
    (5) Start the thread.
  • Advantages of implementing the Runable interface over inheriting the Thread class:
    (1) Avoid the limitation of Java single inheritance;
    (2) It is suitable for multiple codes of the same program to process the same resource (when creating multiple threads, we pass the same MyRunable object as a parameter, which shows that it is the same resource). It effectively separates the thread from the program code and data, which better reflects the object-oriented design idea.
public class MyRunable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
        }
    }
}
    public static void main(String[] args) {
        MyRunable mr = new MyRunable();

        //Thread (Runable target)
        //Thread t1 = new Thread(mr);
        //Thread t2 = new Thread(mr);

        Thread t1 = new Thread(mr,"high-speed rail");
        Thread t2 = new Thread(mr,"aircraft");

        t1.start();
        t2.start();
    }

Keywords: Java Back-end

Added by eternalprophet on Sun, 02 Jan 2022 21:30:06 +0200