Multithreading foundation 1

Keywords: Java Back-end

Let's start with two concepts: process and thread  

         Process: a running program, which is an independent unit of the system for resource allocation and call. Each process has its own memory space and system resources.

         Thread: a single sequential control flow in a process. It is an execution path. If a process has only one execution path, it is called a single threaded program. If a process has multiple execution paths, it is called a multithreaded program. (threads are included in the process)  

How do I create threads?

          The first method: customize a subclass to inherit the Thread class. Note that the run() method needs to be overridden in this subclass, and then create a subclass object to start the Thread

  We simply write subclasses:

public class MyThread extends Thread{
    /*
        Why use the run method?
       When the thread executes, only the code added to the run() method is executed, and the others are not executed
     */
    @Override
    public void run(){
        /*
        Generally speaking, the code executed by threads is time-consuming,
        In order to make the simulation time-consuming, I use loop simulation here
         */
        for(int i =0;i<10;i++){
            System.out.println(i);
        }
    }
}
 public static void main(String[] args) {
        //Every time an object is created, a thread is created
        //Create an object according to the subclass we write, and then use start to enable it. This is the call of the thread
        MyThread myThread = new MyThread();
        myThread.start();
    }

The difference between run() and start():  

         The call of run() only encapsulates the code executed by the thread, but the direct call is an ordinary method call
  To call the start() method, first start a thread separately, and then the JVM calls the run() method of the thread

Simulate the multithreading environment, and create at least two or more threads. Next, we write two threads for preparation

  Multiple threads share the resources of the same process (heap memory and method area), but the stack memory is independent. One thread has one stack. So they are still grabbing CPU resources for execution. Only one thread can execute at a point in time. Moreover, it is not certain who gets it, so it causes the randomness of thread operation.

Multiple threads preempt resources to run. What if you want to know which process the current running result is, and how to get the name of the thread?

//Name the thread through the method:
//void setName(String name) changes the name of this thread to be equal to the parameter name 
  MyThread myThread1 = new MyThread();
  MyThread myThread2 = new MyThread();
  myThread1.setName("Zhang San");
  myThread2.setName("Zhang Sanfeng");
  myThread1.start();
  myThread2.start();

//The above output statement of MyThread class plus getName() returns the name of the current thread


Output results
0--Zhang Sanfeng
0--Zhang San
1--Zhang Sanfeng
1--Zhang San
2--Zhang Sanfeng
3--Zhang Sanfeng
...

  Thinking questions:
        Is the JVM started single threaded or multi-threaded?
          It is multithreaded because at least the program has a main thread and a garbage collection thread.
        Therefore, when the JVM is started, it is required to have at least two threads. When the JVM is started, it is multithreaded.

  How Java programs work:
            The java command will start the java virtual machine and the JVM, which is equivalent to starting an application,
            That is to start a process.
            The process will automatically start a "main thread", and then the main thread will call the main method of a class.
            So the main method runs in the main thread. All previous programs were single threaded.

Thread scheduling:

Threads have two scheduling models:

Time sharing scheduling model: all threads use the right to use the CPU in turn, and evenly allocate the time slice of CPU occupied by each thread

Preemptive scheduling model: give priority to the threads with high priority to use CPU. If the threads have the same priority, one will be selected randomly. The threads with high priority will obtain relatively more CPU time slices.

Java uses a preemptive scheduling model. Demonstrates how to set and get thread priority

public final int getPriority()

public final void setPriority(int newPriority)

/*
    stay getPriority The priority range 1 is found in the source code of-10,Those without priority are 5
    public final static int MIN_PRIORITY = 1;
    public final static int NORM_PRIORITY = 5;
    public final static int MAX_PRIORITY = 10;
/*

MyPriorityThread t1 = new MyPriorityThread();
        System.out.println(t1.getPriority());//Get thread priority
        MyPriorityThread t2 = new MyPriorityThread();
        t2.setPriority(6);//Set the priority of t2 to high
        t1.setName("t1");
        t2.setName("t2");
        t1.start();
        t2.start();

Partial output results: 
t1:0
t2:0
t1:1
t2:1
t1:2
t1:3
t1:4

Finding that a thread has a high priority only means getting CPU The probability of time slice will be higher, but it is not absolutely certain to obtain it

Multiple processes preempt resources. I want threads to pause for a period of time after grabbing resources

public class ThreadSleepDemo {
    public static void main(String[] args) {
        MySleepThread t1 = new MySleepThread();
        MySleepThread t2 = new MySleepThread();
        MySleepThread t3 = new MySleepThread();

        t1.setName("t1");
        t2.setName("t2");
        t3.setName("t3");

        t1.start();
        t2.start();
        t3.start();

    }
}

public class MySleepThread extends Thread {
    @Override
    public void run() {
        for(int i =0;i<100;i++){
            System.out.println(getName()+":"+i);

            //Adding a sleep method,
            //Sleep for one second, 1 second = 1000 milliseconds
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

Join thread: public final void join()   (function: execute first, and other threads wait for this thread to die)

  matters needing attention:

Before the thread is set to join the thread, first change the thread to the ready state, that is, call the start() method

public class ThreadJoinDemo {
    public static void main(String[] args) {
        MyJoinThread mt1 = new MyJoinThread();
        MyJoinThread mt2 = new MyJoinThread();
        MyJoinThread mt3 = new MyJoinThread();
        mt1.setName("Process 1");
        mt2.setName("Process 2");
        mt3.setName("Process 3");
        mt1.start();

        try {
            mt1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        mt2.start();
        mt3.start();
    }
}

public class MyJoinThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + ":" + i);
        }
    }

Comity thread:   public static void yield()
Pauses the currently executing thread object and executes other threads
Its function is to make multiple threads more harmonious, and it does not necessarily guarantee that multiple threads can be executed by one person at a time

Add Thread.yield() in the subclass created; method

Daemon thread: public final void setDaemon(boolean on)
This method marks the thread object as a daemon thread or a non daemon thread.
When the running program has only one thread and is a daemon thread, the Java virtual machine exits

  Usage:
Daemon object. setDaemon(true);
 

stop and interrupt methods:

/*
     public final void stop():
    Stop the running thread, and the remaining code of the run method will not be executed. This method has passed and is discarded, but it can still be used.
     public void interrupt():
    Interrupt the running thread. The interrupted thread completes the execution of the run method and throws an exception
                                        java.lang.InterruptedException: sleep interrupted

*/
public class ThreadStopDemo {
    public static void main(String[] args) {
        MyStopThread t1 = new MyStopThread();
        t1.start();

        try {
            Thread.sleep(3000);
//            t1.stop();
            t1.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

import java.util.Date;
public class MyStopThread extends Thread {
    @Override
    public void run() {
        System.out.println("Start execution time:" + new Date());

        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("End time:" + new Date());
        System.out.println("hello");


    }
}

Implementation method 2 of multithreading:   Implement Runnable interface
            1. Create a custom class to implement the Runnable interface
            2. Override the run() method
            3. Create an object of a custom class
            4. Create an object of Thread class, and pass the custom class object created in step 3 as a parameter to the construction method

ublic class MyRunnableDemo {
    public static void main(String[] args) {
        //Create an object of a custom class
        MyRunnbale myRunnbale1 = new MyRunnbale();

        Thread t1 = new Thread(myRunnbale1);
        Thread t2 = new Thread(myRunnbale1);

        t1.setName("Process 1");
        t2.setName("Process 2");
        t1.start();
        t2.start();

    }
}

public class MyRunnbale extends Thread {
    @Override
    public void run() {
        for (int i =1;i<=100;i++){
            //Since there is no getName() method in the Runnable interface implemented, the method in the Thread class cannot be used here
            //getName() method
            //Indirect call, because currentThread() is static, you can directly call through the class name to get the current
            //The Thread object (Thread type) that executes the run method, so getName() can be called
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

Posted by sargus on Fri, 22 Oct 2021 17:14:40 -0700