Three ways of implementing threads in Java multithreading and their comparison

Posted by jalperin on Wed, 26 Jan 2022 00:18:05 +0100

Method 1: inherit Thread class

step

  • Define a MyThread class and inherit the Thread class
  • Override the run method in the MyThread class
  • Create an object of the MyThread class
  • Start thread

MyThred class

package com.cmy.threaddemo;

/**
 * @author Ming Yong Chen
 */
public class MyThread extends Thread {
    /**
     * Method executed after the thread is turned on
     */
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("The thread is turned on" + i);
        }
    }
}

Test class

package com.cmy.threaddemo;

/**
 * @author Ming Yong Chen
 */
public class Demo {
    public static void main(String[] args) {
        // Create a thread object
        MyThread t1 = new MyThread();
        // Open a thread
        t1.start();
        // Create a thread object
        MyThread t2 = new MyThread();
        // Open a thread
        t2.start();
    }
}

reflection

  • Why override the run() method

    Because the run() method 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. If it is called directly, it is equivalent to executing ordinary methods without starting the thread

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

Method 2: implement Runnable interface

step

  • Define a MyRunnable class to implement the Runnable interface
  • Override the run() method in the MyRunnable class
  • Create an object of the MyRunnable class
  • Create the object of Thread class and take the object of MyRunnable as the parameter of the construction method
  • Start thread

MyRunnable class

package com.cmy.threaddemo2;

/**
 * @author Ming Yong Chen
 */
public class MyRunnable implements Runnable {

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

Test class

package com.cmy.threaddemo2;

/**
 * @author Ming Yong Chen
 */
public class Demo {
    public static void main(String[] args) {
        // Create MyRunnable object
        MyRunnable myRunnable1 = new MyRunnable();
        // Create thread object
        Thread t1 = new Thread(myRunnable1);
        // Start thread
        t1.start();

        // Create MyRunnable object
        MyRunnable myRunnable2 = new MyRunnable();
        // Create thread object
        Thread t2 = new Thread(myRunnable2);
        // Start thread
        t2.start();
    }
}

Mode 3: Callable and Future

step

  • 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 object of MyCallable class as the parameter of the construction method
  • Create the object of MyThread class and take the object of FutureTask as the parameter of the construction method
  • Start thread
  • Call the get() method to get the result after the thread is started

MyCallable class

package com.cmy.threaddemo3;

import java.util.concurrent.Callable;

/**
 * @author Ming Yong Chen
 */
public class MyCallable implements Callable<String> {

    @Override
    public String call() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println("having dinner" + i);
        }
        // The return value represents the result after the thread runs
        return "Full, burp~";
    }
}

Override the call method. The return value of the call method represents the result after the thread runs

Test class

package com.cmy.threaddemo3;


import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

/**
 * @author Ming Yong Chen
 */
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 myCallable = new MyCallable();
        // You can get the result after the Thread is executed, or pass it to the Thread object as a parameter
        FutureTask<String> ft = new FutureTask<>(myCallable);
        // Create thread object
        Thread thread = new Thread(ft);
        // Open thread
        thread.start();
        // Get the results after the thread runs
        String s = ft.get();
        System.out.println(s);
    }
}

The object of FutureTask class can obtain the result after the thread runs through the get() method, that is, the return value of the call() method. Note that the get() method cannot be invoked before the thread opens.

Comparison of three methods

advantageshortcoming
Implement Runnable and Callable interfacesIt has strong expansibility. It can inherit other classes while implementing this interface.The programming is relatively complex and the methods in the Thread class cannot be used directly
Inherit Thread classProgramming is relatively simple. You can directly use the methods in the Thread classPoor extensibility, unable to inherit other classes

Topics: Java Multithreading thread