Multithreading learning notes 1

Concept:

Concurrency and parallelism

  • Parallelism: multiple instructions are executed simultaneously on multiple CPUs at the same time

Convenient memory: five people (multiple CPUs) play black games, one mobile phone, and five people execute at the same time For parallel

  • Concurrency: at the same time, multiple instructions are executed alternately on a single cpu

Convenient memory: a person playing black games with five mobile phones needs to quickly switch between the five mobile phones. At a certain moment, the person only operates on one mobile phone, so it is executed alternately

Processes and threads

Process: is running software

  • Independence: process is a basic unit that can run independently, and 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 generated 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

Convenient memory: 360 software can perform garbage cleaning / computer killing at the same time, and each execution path is a thread

  • Single thread: if a process has only one execution path, it becomes a single threaded program
  • Multithreading: if a process has multiple execution paths, it becomes a multithreaded program

Implementation scheme of multithreading

  • It is implemented by inheriting the Thread class
  • Implement the Runnable interface
  • It is implemented by Callable and Future interface

Scheme 1: inherit Thread class

  • 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
//Custom thread class
public class MyThread extends Thread {
    @Override
    public void run() {
        //Logical code to be executed by multithreading
        for (int i = 0; i < 100; i++) {
            System.out.println("thread "+Thread.currentThread().getName()+"Print"+i);
        }
    }
}


//Test class
public class Demo {
    public static void main(String[] args) {
        MyThread my1= new MyThread();
        MyThread my2= new MyThread();
        my1.start();//The start method interacts with the local operating system to start a thread
        my2.start();
    }
}

run(): encapsulates the thread execution code and calls it directly, which is equivalent to the call of an ordinary method without starting the thread

start(): start the thread; The run() method of this thread is then called by the JVM

Scheme 2: implement Runnable interface

  • Define a class MyRunnable 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 the thread
public class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("thread "+Thread.currentThread().getName()+"Print"+i);
        }
    }
}


//Test class
public class MyTest {
    public static void main(String[] args) {
        Thread thread1 = new Thread(new MyRunnable());
        Thread thread2 = new Thread(new MyRunnable());
        thread1.start();
        thread2.start();
    }
}

Scenario 3:Callable and Future

  • Define a class MyCallable to implement the callable interface
  • Override the call() method in the 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
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()+"Play games"+i);
        }
        //The return value is the interface after the thread runs,
        // The return value type is consistent with the T type of callable < T >
        return "victory";
    }
}

//Test class
public class MyTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyCallable mc = new MyCallable();
        FutureTask<String> ft = new FutureTask<>(mc);

        Thread th= new Thread(ft);
        th.start();

        //It is placed after the thread is started. If the thread does not end, it will wait all the time
        String s = ft.get();
        System.out.println(s);
    }
}

Summary:

 

advantageshortcoming
Implement the Runnable\Callable interfaceStrong expansibility. You can inherit other classes while implementing this interfaceProgramming is relatively complex, so you can't directly use the methods in the Thread class
Inherit Thread classProgramming is relatively simple. You can directly use the methods in the Thread classPoor extensibility, unable to inherit other classes


  

Keywords: Java Multithreading

Added by rizi on Sun, 26 Dec 2021 05:59:39 +0200