Java basics - multi-threaded creation

(1) What is a thread?

  • A thread is an execution path within a program.
  • If there is only one execution path in the program, then the program is a single-threaded program.

 (2) What is multithreading?

  • Multithreading refers to the technology of implementing multiple execution processes from hardware and software.

(3) Creation of multithreading

3.1. Inherit the Thread class

  • Inherit the Thread class (define a subclass to inherit the thread class java.lang.Thread)
  • Override the run method
  • create thread object
  • Call the start() method to start

Notice:

1. Why not call the run method directly, but call start to start the thread

  • Calling the run method directly will be executed as a normal method, which is equivalent to single-threaded execution.
  • Only calling the start method starts a new thread for execution. 

2. Don't put the main thread before the child thread, because the main thread runs first, which is equivalent to the effect of a single thread.

3. Although the code is simple, there is a limitation of single inheritance. After the thread class inherits Thread, it cannot inherit other classes, which is not easy to expand.

/**
   目标:多线程的创建方式一:继承Thread类实现。
 */
public class ThreadDemo1 {
    public static void main(String[] args) {
        // 3、new一个新线程对象
        Thread t = new MyThread();
        // 4、调用start方法启动线程(执行的还是run方法)
        t.start();

        for (int i = 0; i < 5; i++) {
            System.out.println("主线程执行输出:" + i);
        }

    }
}

/**
   1、定义一个线程类继承Thread类
 */
class MyThread extends Thread{
    /**
       2、重写run方法,里面是定义线程以后要干啥
     */
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("子线程执行输出:" + i);
        }
    }
}

3.2. Implement the Runnable interface

  • Define a thread task class MyRunnable to implement the Runnable interface and override the run() method.
  • Create a MyRunnable task class.
  • Hand over the MyRunnable task object to Thread for processing.
  • Call the start() method of the thread object to start the thread.
  • Thread constructor:

Advantages: The thread task class only implements the interface, can continue to inherit the class and implement the interface, and has strong scalability.

Disadvantages: There is an extra layer of object packaging for programming. If the thread has an execution result, it cannot be returned directly.

/**
   目标:学会线程的创建方式二,理解它的优缺点。
 */
public class ThreadDemo2 {
    public static void main(String[] args) {
        // 3、创建一个任务对象
        Runnable target = new MyRunnable();
        // 4、把任务对象交给Thread处理
        Thread t = new Thread(target);
        // Thread t = new Thread(target, "1号");
        // 5、启动线程
        t.start();

        for (int i = 0; i < 10; i++) {
            System.out.println("主线程执行输出:" + i);
        }
    }
}

/**
   1、定义一个线程任务类 实现Runnable接口
 */
class MyRunnable  implements Runnable {
    /**
       2、重写run方法,定义线程的执行任务的
     */
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("子线程执行输出:" + i);
        }
    }
}

 (anonymous inner class form)

  • An anonymous inner class object of Runnable can be created.
  • Hand it over to Thread.
  • Call start() on the thread object to start the thread.
/**
   目标:学会线程的创建方式二(匿名内部类方式实现,语法形式)
 */
public class ThreadDemo2Other {
    public static void main(String[] args) {
        Runnable target = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println("子线程1执行输出:" + i);
                }
            }
        };
        Thread t = new Thread(target);
        t.start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println("子线程2执行输出:" + i);
                }
            }
        }).start();

        new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    System.out.println("子线程3执行输出:" + i);
            }
        }).start();

        for (int i = 0; i < 10; i++) {
            System.out.println("主线程执行输出:" + i);
        }
    }
}

3.3. Use Callable, FutureTask interface implementation

1. Get the task object

  • Define the class to implement the Callable interface, rewrite the call method, and encapsulate the things to be done.
  • Use FutureTask to encapsulate the Callable object into a thread task object.

2. Hand over the thread task object to Thread for processing.

3. Call the start method of Thread to start the thread and execute the task.

4. After the thread is executed, use the get method of FutureTask to obtain the task execution result.

 

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
   目标:学会线程的创建方式三:实现Callable接口,结合FutureTask完成。
 */
public class ThreadDemo3 {
    public static void main(String[] args) {
        // 3、创建Callable任务对象
        Callable<String> call = new MyCallable(100);
        // 4、把Callable任务对象 交给 FutureTask 对象
        //  FutureTask对象的作用1: 是Runnable的对象(实现了Runnable接口),可以交给Thread了
        //  FutureTask对象的作用2: 可以在线程执行完毕之后通过调用其get方法得到线程执行完成的结果
        FutureTask<String> f1 = new FutureTask<>(call);
        // 5、交给线程处理
        Thread t1 = new Thread(f1);
        // 6、启动线程
        t1.start();


        Callable<String> call2 = new MyCallable(200);
        FutureTask<String> f2 = new FutureTask<>(call2);
        Thread t2 = new Thread(f2);
        t2.start();

        try {
            // 如果f1任务没有执行完毕,这里的代码会等待,直到线程1跑完才提取结果。
            String rs1 = f1.get();
            System.out.println("第一个结果:" + rs1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            // 如果f2任务没有执行完毕,这里的代码会等待,直到线程2跑完才提取结果。
            String rs2 = f2.get();
            System.out.println("第二个结果:" + rs2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

/**
    1、定义一个任务类 实现Callable接口  应该申明线程任务执行完毕后的结果的数据类型
 */
class MyCallable implements Callable<String>{
    private int n;
    public MyCallable(int n) {
        this.n = n;
    }

    /**
       2、重写call方法(任务方法)
     */
    @Override
    public String call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= n ; i++) {
            sum += i;
        }
        return "子线程执行的结果是:" + sum;
    }
}

3.4. Comparison of three methods:

 

Guess you like

Origin blog.csdn.net/weixin_61275790/article/details/130308308