[Yugong series] January 2022 Java Teaching Course 59 - multithreading

Posted by KissMyBrain on Sat, 15 Jan 2022 13:09:04 +0100

Article catalog

1, Multithreading

1. Simple understanding of multithreading

It refers to the technology that multiple threads execute concurrently from software or hardware. Computers with multithreading capability can execute multiple threads at the same time due to hardware support, so as to improve performance.

2. Concurrency and parallelism

  • Parallelism: multiple instructions are executed simultaneously on multiple CPU s at the same time.
  • Concurrency: at the same time, multiple instructions are executed alternately on a single CPU.

3. Processes and threads

  • Process: is a running program Independence: a process is a basic unit that can run independently. It is also an independent unit for system resource allocation and scheduling Dynamic: the essence of a process is an execution process of a program. A process is produced and dies dynamically Concurrency: any process can execute concurrently with other processes
  • Thread: it is a single sequential control flow in a process and an execution path Single thread: if a process has only one execution path, it is called a single threaded program Multithreading: if a process has multiple execution paths, it is called a multithreaded program

4. Implement multithreading mode 1: inherit Thread class

  • Method introduction
  • Implementation steps
    • Define a class MyThread to inherit the Thread class
    • Override the run() method in the MyThread class
    • Create an object of the MyThread class
    • Start thread
  • Code demonstration
public class MyThread extends Thread {
    @Override
    public void run() {
        for(int i=0; i<100; i++) {
            System.out.println(i);
        }
    }
}
public class MyThreadDemo {
    public static void main(String[] args) {
        MyThread my1 = new MyThread();
        MyThread my2 = new MyThread();

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

        //void start() causes this thread to start execution; The Java virtual machine calls the run method of this thread
        my1.start();
        my2.start();
    }
}

Two small problems

  • Why override the run() method? Because run() is used to encapsulate the code executed by the thread
  • What is the difference between the run() method and the start() method? run(): encapsulates the code executed by the thread. It is called directly, which is equivalent to the call of ordinary methods start(): start the thread; The run() method of this thread is then called by the JVM

5. Implement multithreading mode 2: implement Runnable interface

  • Thread construction method
  • Implementation steps
    • Define a class MyRunnable to implement the Runnable interface
    • Override the run() method in the MyRunnable class
    • Create an object of the MyRunnable class
    • Create an object of Thread class and take the MyRunnable object as the parameter of the construction method
    • Start thread
  • Code demonstration
public class MyRunnable implements Runnable {
    @Override
    public void run() {
        for(int i=0; i<100; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}
public class MyRunnableDemo {
    public static void main(String[] args) {
        //Create an object of the MyRunnable class
        MyRunnable my = new MyRunnable();

        //Create an object of Thread class and take the MyRunnable object as the parameter of the construction method
        //Thread(Runnable target)
//        Thread t1 = new Thread(my);
//        Thread t2 = new Thread(my);
        //Thread(Runnable target, String name)
        Thread t1 = new Thread(my,"Tank");
        Thread t2 = new Thread(my,"aircraft");

        //Start thread
        t1.start();
        t2.start();
    }
}

6. Implement multithreading mode 3: implement Callable interface

  • Method introduction
  • Implementation steps

Define a class MyCallable to implement the Callable interface

Override in MyCallable() class

Create an object of the MyCallable class

Create the FutureTask object of the implementation class of Future, and take the MyCallable object as the parameter of the construction method

Create an object of Thread class and take FutureTask object as the parameter of construction method

Start thread

Then call the get method to get the result after the thread ends.

  • Code demonstration
public class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println("Confess to the girl" + i);
        }
        //The return value represents the result after the thread runs
        return "promise";
    }
}
public class Demo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //After the thread is started, you need to execute the call method inside
        MyCallable mc = new MyCallable();

        //Thread t1 = new Thread(mc);

        //You can get the results after the Thread is executed It can also be passed as a parameter to the Thread object
        FutureTask<String> ft = new FutureTask<>(mc);

        //Create thread object
        Thread t1 = new Thread(ft);

        String s = ft.get();
        //Open thread
        t1.start();

        //String s = ft.get();
        System.out.println(s);
    }
}
  • Comparison of three implementation methods

Implement Runnable and Callable interfaces

Advantages: strong extensibility. You can inherit other classes while implementing this interface

Disadvantages: the programming is relatively complex and the methods in the Thread class cannot be used directly

Inherit Thread class

Benefits: programming is relatively simple. You can directly use the methods in the Thread class

Disadvantages: poor extensibility, unable to inherit other classes

7. Set and get thread name

  • Method introduction
  • Code demonstration
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 class MyThreadDemo {
    public static void main(String[] args) {
        MyThread my1 = new MyThread();
        MyThread my2 = new MyThread();

        //void setName(String name): change the name of this thread to be equal to the parameter name
        my1.setName("high-speed rail");
        my2.setName("aircraft");

        //Thread(String name)
        MyThread my1 = new MyThread("high-speed rail");
        MyThread my2 = new MyThread("aircraft");

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

        //static Thread currentThread() returns a reference to the thread object currently executing
        System.out.println(Thread.currentThread().getName());
    }
}

8. Thread hibernation

  • correlation method
  • Code demonstration
public class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName() + "---" + i);
        }
    }
}
public class Demo {
    public static void main(String[] args) throws InterruptedException {
        /*System.out.println("Before going to bed ");
        Thread.sleep(3000);
        System.out.println("Wake up ");*/

        MyRunnable mr = new MyRunnable();

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

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

9. Thread priority

  • Thread scheduling

Two scheduling modes

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 more CPU time slices

Java uses a preemptive scheduling model

Randomness

If the computer has 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 the instruction. Therefore, the execution of multithreaded programs is random, because it is not certain who grabs the right to use the CPU

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-RwjFsAqb-1641718205043)(.\img multi thread example picture. png)]

  • Priority correlation method
  • Code demonstration
public class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + "---" + i);
        }
        return "Thread execution is complete";
    }
}
public class Demo {
    public static void main(String[] args) {
        //Priority: 1 - 10 default: 5
        MyCallable mc = new MyCallable();

        FutureTask<String> ft = new FutureTask<>(mc);

        Thread t1 = new Thread(ft);
        t1.setName("aircraft");
        t1.setPriority(10);
        //System.out.println(t1.getPriority());//5
        t1.start();

        MyCallable mc2 = new MyCallable();

        FutureTask<String> ft2 = new FutureTask<>(mc2);

        Thread t2 = new Thread(ft2);
        t2.setName("Tank");
        t2.setPriority(1);
        //System.out.println(t2.getPriority());//5
        t2.start();
    }
}

10. Daemon thread

  • correlation method
  • Code demonstration
public class MyThread1 extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName() + "---" + i);
        }
    }
}
public class MyThread2 extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + "---" + i);
        }
    }
}
public class Demo {
    public static void main(String[] args) {
        MyThread1 t1 = new MyThread1();
        MyThread2 t2 = new MyThread2();

        t1.setName("goddess");
        t2.setName("spare tire");

        //Set the second thread as the daemon thread
        //When the normal thread is executed, there is no need for the daemon thread to continue running
        t2.setDaemon(true);

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