Several ways Java implements multithreading are summarized

  • 2020-05-07 19:34:49
  • OfStack

Let's start with a sample piece of code


import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

public class Main {

  public static void main(String[] args) {
    // methods 1 Inherited: Thread
    int i = 0;
//    for(; i < 100; i++){
//      System.out.println(Thread.currentThread().getName() + " " + i);
//      if (i == 5) {
//        ThreadExtendsThread threadExtendsThread = new ThreadExtendsThread();
//        threadExtendsThread.start();
//      }
//    }
    
    // methods 2 : Runnable
//    for(i = 0; i < 100; i++){
//      System.out.println(Thread.currentThread().getName() + " " + i);
//      if (i == 5) {
//        Runnable runnable = new ThreadImplementsRunnable();
//        new Thread(runnable).start();
//        new Thread(runnable).start();
//      }
//    }

    // methods 3 : Callable interface 
    Callable<Integer> callable = new ThreadImplementsCallable();
    FutureTask<Integer> futureTask = new FutureTask<>(callable);
    for(i = 0; i < 100; i++){
      System.out.println(Thread.currentThread().getName() + " " + i);
      if (i == 5) {
        new Thread(futureTask).start();
        new Thread(futureTask).start();
      }
    }
    try {
      System.out.println("futureTask ruturn: " + futureTask.get());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

}

Let's take a closer look at some of the ways Java implements multithreading

method 1, inherited from Thread


public class ThreadExtendsThread extends Thread {
  private int i;
  @Override
  public void run() {
    for(; i < 100; i++) {
      System.out.println(getName() + " " + i); 
    }
  }
}

The run method is the thread execution body, and the ThreadExtendsThread object is the thread object.

method 2, Runnable interface


public class ThreadImplementsRunnable implements Runnable {
  private int i;
  @Override
  public void run() {
    for(; i < 100; i++){
      System.out.println(Thread.currentThread().getName() + " " + i);
    }
  }
}

The run method is the body of thread execution. When used, New1 Thread objects are passed to Thread objects as target objects. And the same Runnable object can be used as target for multiple Thread, and these threads all share instance variables for Runnable objects.

method 3, implement Callable interface


import java.util.concurrent.Callable;

public class ThreadImplementsCallable implements Callable<Integer> {
  private int i;
  
  @Override
  public Integer call() throws Exception {
    for(; i < 100; i++){
      System.out.println(Thread.currentThread().getName() + " " + i);
    }
    return i;
  }
}

The Callable interface is similar to the Runnable interface, but more powerful than the other one. The thread executor is the call method, which has a return value and can throw an exception. When used, the Callable object is wrapped as an FutureTask object, and the return value type is specified by generics. You can later call the get method of FutureTask to fetch the execution results.


Related articles: