Java Multithreading 01-05

01-thread, process, multithread

Common methods and multithreading

image-20230317091338680

Note the run() and start() methods

Process and Thread

  • Speaking of the process, we have to talk about the procedure. A program is an ordered collection of instructions and data, which itself has no meaning of operation and is a static concept.
  • A process is an execution process of executing a program, and it is a dynamic concept. Is the unit of system resource allocation
  • Usually a process can contain several threads, of course there is at least one thread in a process, otherwise there is no meaning of existence. Thread is the unit of CPU scheduling and execution.

Note: Many multi-threads are simulated. The real multi-threading refers to having multiple cu, that is, multi-core such as a server. If it is simulated multi-threading, that is, in the case of a CPU, at the same time point, the CPU can only execute one code, because the switching is very fast, so there is a mistake of simultaneous execution.

The core concepts of this chapter

  • A thread is an independent path of execution;
  • When the program is running, even if you don’t create a thread yourself, there will be multiple threads in the background, such as the main thread and gc thread;
  • main() is called the main thread, which is the entry point of the system and is used to execute the entire program;
  • In a process, if multiple threads are opened up, the running of the threads is arranged and scheduled by the scheduler. The scheduler is closely related to the operating system, and the sequence cannot be regarded as intervention.
  • When operating on the same resource, there will be resource snatching problems, and concurrency control needs to be added;
  • Threads will bring additional overhead, such as cpu scheduling time, concurrency control overhead.
  • Each thread interacts in its own working memory, and improper memory control will cause data inconsistency

02-Thread creation

Inherit the Thread class (emphasis)

  1. Custom thread class inherits Thread class
  2. Rewrite the run() method and write the thread execution body
  3. Create a thread object and call the start() method to start the thread

The thread opening does not necessarily execute immediately, see the cpu scheduling arrangement

package com.demo01;

//1. Inherit the Thread class 2. Rewrite the run() method 3. Call the start() method
public class TestThread1 extends Thread{<!-- -->
    @Override
    public void run() {<!-- -->
        for (int i = 0; i < 20; i ++ ) {<!-- -->
            System.out.println("I'm looking at the code ----" + i);
        }
    }
    //main method, main thread
    public static void main(String[] args) {<!-- -->
        //Create a thread object
        TestThread1 testThread1 = new TestThread1();
        //Call the start() method to start the thread
        testThread1. start();
        // normal method
        //testThread1.run();
        for (int i = 0; i < 20; i ++ ) {<!-- -->
            System.out.println("I'm learning multithreading----" + i);
        }
    }
}

Implement the Runnable interface (emphasis)

Another way to create a thread is to declare a class that implements the Runnable interface. That class then implements the run method. An instance of the class can then be allocated, passed as a parameter when the Thread is created, and started.

  • Define the MyRunnable class to implement the Runnable interface
  • Implement the run() method and write the thread execution body
  • Create a thread object and call the start() method to start the thread

Thread implements the Runnable interface, and the class written by myself implements the Runnable interface, and then throws the class written by myself into Thread (the class written by myself)

 public Thread(Runnable target) {<!-- -->
        this((ThreadGroup)null, target, "Thread-" + nextThreadNum(), 0L);
    }

runnable

public interface Runnable {<!-- -->
    void run();
}

Because of java single inheritance, it is recommended to use the Runnable interface

package com.demo01;

//Create thread method 2: implement the runnable interface, rewrite the run method, the execution thread needs to be thrown into the runnable interface implementation class, and call start
public class TestThread3 implements Runnable {<!-- -->
    @Override
    public void run() {<!-- -->
        //run method thread body
        for (int i = 0; i < 20; i ++ ) {<!-- -->
            System.out.println("I'm looking at the code ----" + i);
        }
    }
    //main method, main thread
    public static void main(String[] args) {<!-- -->
        //Create an implementation class object of the Runnable interface
        TestThread3 testThread3 = new TestThread3();
        //Create a thread object and start our thread through the thread object
// Thread thread = new Thread(testThread3);

// thread. start();
        new Thread(testThread3).start();

        for (int i = 0; i < 20; i ++ ) {<!-- -->
            System.out.println("I'm learning multithreading----" + i);
        }
    }
}

Case: grabbing a train ticket

package com.demo01;

//Multiple threads operate on the same object at the same time
//Example of buying a train ticket

//Find the problem: when multiple threads operate on the same resource, the thread is not safe and the data is disordered
public class TestThread4 implements Runnable{<!-- -->

    //number of votes
    private int ticketNums = 10;
    @Override
    public void run() {<!-- -->
        while (true){<!-- -->
            if(ticketNums<=0){<!-- -->
                break;
            }
            //simulate delay
            try {<!-- -->
                Thread. sleep(200);
            } catch (InterruptedException e) {<!-- -->
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "--> got the first" + ticketNums-- + "ticket");
        }
    }

    public static void main(String[] args) {<!-- -->
        TestThread4 ticket=new TestThread4();

        new Thread(ticket,"Xiao Ming").start();
        new Thread(ticket,"teacher").start();
        new Thread(ticket,"Scalper").start();
    }
}

Case: The Tortoise and the Hare-Race

  1. First come to the track distance, and then get closer and closer to the finish line
  2. Determine if the game is over
  3. print out the winner
  4. The tortoise and the hare start
  5. In the story, the tortoise wins, and the rabbit needs to sleep, so let’s simulate the rabbit to sleep
  6. Finally, the tortoise wins the race
package com.demo01;

//Simulate the tortoise and the hare race
public class Race implements Runnable {<!-- -->
    private static String winner;

    @Override
    public void run() {<!-- -->

        for (int i = 0; i <= 100; i ++ ) {<!-- -->
            //Simulate a rabbit to rest every 10 steps
            if(Thread.currentThread().getName().equals("rabbit") & amp; & amp;i ==0){<!-- -->
                try {<!-- -->
                    Thread. sleep(5);
                } catch (InterruptedException e) {<!-- -->
                    e.printStackTrace();
                }
            }

            //Determine if the game is over
            boolean flag=gameOver(i);
            // Stop the program if the game is over
            if (flag){<!-- -->
                break;
            }
            System.out.println(Thread.currentThread().getName() + "--> ran" + i + "step");
        }
    }

    //Determine whether the game is completed
    private boolean gameOver(int steps) {<!-- -->
        //Check if there is a winner
        if (winner != null) {<!-- -->//There is already a winner
            return true;
        }
        if (steps == 100) {<!-- -->
            winner = Thread.currentThread().getName();
            System.out.println("Winner is " + winner);
            return true;
        }
        return false;
    }

    public static void main(String[] args) {<!-- -->
        Race race = new Race();

        new Thread(race,"rabbit").start();
        new Thread(race,"turtle").start();
    }
}

Implement the Callable interface (understand)

  1. To implement the Callable interface, the return value type is required
  2. Rewrite the call method, you need to throw an exception
  3. create target object
  4. Create execution service: ExecutorService ser = Executors.newFixedThreadPool(1);
  5. Submit execution: Futureresult1=ser.submit(t1);
  6. Get the result: boolean r1=result1.get();
  7. Close the service: ser.shutdownNow();

Callable benefits

  1. You can define the return value
  2. can throw an exception
package com.demo02;

import com.demo01.TestThread2;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;

//Thread creation method 3: implement the Callable interface
/*
The benefits of callable
1. You can define the return value
2. Can throw an exception
 */
public class TestCallable implements Callable<Boolean> {<!-- -->
    private String url;//Network image address
    private String name;//saved file name

    public TestCallable(String url, String name) {<!-- -->
        this.url = url;
        this.name = name;
    }

    //Download the execution body of the image thread
    @Override
    public Boolean call() {<!-- -->
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url, name);
        System.out.println("Downloaded file name: " + name);
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {<!-- -->
        TestCallable t1 = new TestCallable("https://gitee.com/sky10241/my-image/raw/master/img/image-20230317091338680.png", "test1.jpg");
        TestCallable t2 = new TestCallable("https://i0.hdslb.com/bfs/article/5caf60959e8f17098b7984c3794203219b9313bb.png@942w_1413h_progressive.webp", "test2.jpg");
        TestCallable t3 = new TestCallable("https://t7.baidu.com/it/u=4198287529,2774471735 & amp;fm=193 & amp;f=GIF", "test3.jpg");
        //1. Create an execution service:
        ExecutorService ser = Executors. newFixedThreadPool(3);
        //2. Submit for execution: Same as the run method
        Future<Boolean> result1 = ser. submit(t1);
        Future<Boolean> result2 = ser. submit(t2);
        Future<Boolean> result3 = ser. submit(t3);
        //3. Get the result:
        boolean r1 = result1. get();
        boolean r2 = result2. get();
        boolean r3 = result3. get();

        System.out.println(r1);
        System.out.println(r2);
        System.out.println(r3);
        //4. Close the service:
        ser. shutdownNow();
    }
}

//Downloader
class WebDownloader {<!-- -->
    public void downloader(String url, String name) {<!-- -->
        try {<!-- -->
            FileUtils.copyURLToFile(new URL(url), new File(name));
        } catch (IOException e) {<!-- -->
            e.printStackTrace();
            System.out.println("IO is abnormal, there is a problem with the downloader method");
        }
    }
}

Summary

Inherit the Thread class

  1. The subclass inherits the Thread class with multi-threading capability
  2. Start the thread: subclass object.start()
  3. Not recommended: avoid

    o

    o

    P

    Single Inheritance Limitations

    \textcolor{red}{DEPRECATED: avoid OOP single inheritance limitations}

    Deprecated: Avoid OOP single inheritance limitations

Implements the Runnable interface

  1. Implement interface Runnable with multi-threading capability
  2. Start the thread: pass in the target object + Thread object.start()
  3. Recommended use: Avoid the limitations of single inheritance, flexible and convenient, and convenient for the same object to be used by multiple threads

    \textcolor{red}{Recommended use: avoid the limitation of single inheritance, flexible and convenient, convenient for the same object to be used by multiple threads}

    Recommended use: Avoid the limitations of single inheritance, flexible and convenient, and convenient for the same object to be used by multiple threads

03-Static Proxy Mode

  1. Both the real object and the proxy object must implement the same interface
  2. The proxy object should represent the real character
  3. benefit
    1. Proxy objects can do many things that real objects cannot
    2. Real objects focus on doing their own thing
  4. The Thread class is equivalent to the wedding company, and the Runnable is equivalent to the real object

04-Lambda expression

  1. λ is the eleventh letter in the Greek alphabet, and its English name is Lambda
  2. Avoid too many definitions of anonymous inner classes
  3. Its essence belongs to the concept of functional programming

image-20230317163607552

Use

  1. define interface
  2. instantiated interface
package com.lambda;

public class TestLambda2 {<!-- -->
    public static void main(String[] args) {<!-- -->
        iLove = a -> System.out.println("i love you lambda-->" + a);
        iLove. love(520);
        
        Happy happy=(a,b,c)->System.out.println(a + b + b + "we have a good time");
        happy. goodtime(1,2,3);
    }
}

interface ILove {<!-- -->
    void love(int a);
}
interface Happy{<!-- -->
    void goodtime(int a,int b,int c);
}

Why use lambda expressions

  1. Avoid too many definitions of anonymous inner classes
  2. Can make your code look very concise
  3. A bunch of meaningless codes are removed, leaving only the core logic.

Maybe you will say, I read Lambda: expression, not only do I not find it concise, but I feel that it is more messy and I can’t understand it. That’s because we haven’t gotten used to it yet. After using it a lot, we get used to it and it’s fine.

Functional interface

  • Understanding Functional Interface (functional interface) is the key to learning Java8 lambda expressions.
  • Definition of functional interface:
    • Any interface that contains only one abstract method is a functional interface.
    • image-20230317165428993
    • For functional interfaces, we can create objects of the interface through lambda expressions.

Summary

  1. A lambda expression can only be reduced to one line with one line of code. If there are multiple lines, wrap it with a code block
  2. The premise is that the interface is a functional interface
  3. Multiple parameters can also remove the parameter type, if you want to remove it, you must remove it, and you must add parentheses

05-thread status

five states

  1. Creation state: a new Theard comes out, and once the thread object is created, it enters the new state
  2. Ready state: When the start() method is called, the thread immediately enters the ready state, but it does not mean that it is scheduled for execution immediately
  3. Blocked state: When sleep, wait or synchronous lock is called, the thread enters the blocked state, that is, the code does not continue to execute. After the blocking event is released, it re-enters the ready state and waits for the cpu to schedule execution.
  4. Running state: Entering the running state, the thread actually executes the code block of the thread body
  5. Death state:

    The thread is interrupted or terminated. Once it enters the dead state, it cannot be started again

    \textcolor{red}{The thread is interrupted or terminated, once it enters the dead state, it cannot be started again}

    The thread is interrupted or terminated. Once it enters the dead state, it cannot be started again

image-20230318081834666

image-20230318083138688