Explain three ways that Java implements multithreading

  • 2020-04-01 04:07:10
  • OfStack

There are two ways to implement multithreading in Java: by inheriting the Thread class and by implementing the runnable interface .

1. Inherit the Thread class and override the parent run() method


 public class thread1 extends Thread {
 
    public void run() {
        for (int i = 0; i < 10000; i++) {
            System.out.println(" I am a thread "+this.getId());
        }
    }
 
    public static void main(String[] args) {
        thread1 th1 = new thread1();
        thread1 th2 = new thread1();
        th1.run();
        th2.run();
    }
   }

The run () method is just a regular method that is executed sequentially, th1.run () being executed after th1.run () is completed, and thus written with only one main thread. Multithreading doesn't make sense, so you should start the thread with the start() method, which automatically calls the run () method. Change the above code to:


 public class thread1 extends Thread {
     
    public void run() {
        for (int i = 0; i < 10000; i++) {
            System.out.println(" I am a thread "+this.getId());
        }
    }
 
    public static void main(String[] args) {
        thread1 th1 = new thread1();
        thread1 th2 = new thread1();
        th1.start();
        th2.start();
    }
}

Start a new thread with the start() method. In this way, regardless of whether the run() method called by th1.start() is executed, continue to execute th2.start() if there is any other code below, and continue to execute without waiting for th2.start() to complete. (the output thread id is randomly alternate output)

2. Implement the runnable interface


public class thread2 implements Runnable {
 
    public String ThreadName;
     
    public thread2(String tName){
        ThreadName = tName;
    }
     
     
    public void run() {
        for (int i = 0; i < 10000; i++) {
            System.out.println(ThreadName);
        }
    }
     
    public static void main(String[] args) {
        thread2 th1 = new thread2(" thread A");
        thread2 th2 = new thread2(" thread B");
        th1.run();
        th2.run();
    }
}


Like Thread's run method, Runnable's run is just a normal method. In the main method, th2.run () must wait for th1.run () to complete before it can be executed, and the program USES only one Thread. For multithreading purposes, also go through Thread's start () method (note :runnable has no start method). The above code is modified as:


public class thread2 implements Runnable {
 
    public String ThreadName;
     
    public thread2(String tName){
        ThreadName = tName;
    }
     
     
    public void run() {
        for (int i = 0; i < 10000; i++) {
            System.out.println(ThreadName);
        }
    }
     
    public static void main(String[] args) {
        thread2 th1 = new thread2(" thread A");
        thread2 th2 = new thread2("Thread-B");
        Thread myth1 = new Thread(th1);
        Thread myth2 = new Thread(th2);
        myth1.start();
        myth2.start();
    }
}


3. Multithreading with results returned using ExecutorService, Callable, Future (after JDK5.0)
Tasks with return values must implement the Callable interface, and similarly, tasks without return values must implement the Runnable interface. After executing the Callable task, you can get a Future Object, on which you can call get to get the Object returned by the Callable task, and combine it with the thread-pool interface ExecutorService to implement the legendary multithreading that returns results. The following provides a complete example of a multithreaded test with returned results, which can be used directly after it has been verified under JDK1.5. The code is as follows:


import java.util.concurrent.*; 
import java.util.Date; 
import java.util.List; 
import java.util.ArrayList; 
  
 
@SuppressWarnings("unchecked") 
public class Test { 
public static void main(String[] args) throws ExecutionException, 
  InterruptedException { 
  System.out.println("---- The program starts running ----"); 
  Date date1 = new Date(); 
  
  int taskSize = 5; 
  //Create a thread pool
  ExecutorService pool = Executors.newFixedThreadPool(taskSize); 
  //Create multiple tasks with return values
  List<Future> list = new ArrayList<Future>(); 
  for (int i = 0; i < taskSize; i++) { 
  Callable c = new MyCallable(i + " "); 
  //Execute the task and get the Future object
  Future f = pool.submit(c); 
  // System.out.println(">>>" + f.get().toString()); 
  list.add(f); 
  } 
  //Turn off the thread pool
  pool.shutdown(); 
  
  //Gets the results of running all concurrent tasks
  for (Future f : list) { 
  //Gets the return value of the task from the Future object and outputs it to the console
  System.out.println(">>>" + f.get().toString()); 
  } 
  
  Date date2 = new Date(); 
  System.out.println("---- End of program ---- , program running time [ " 
   + (date2.getTime() - date1.getTime()) + " Ms. "); 
} 
} 
  
class MyCallable implements Callable<Object> { 
private String taskNum; 
  
MyCallable(String taskNum) { 
  this.taskNum = taskNum; 
} 
  
public Object call() throws Exception { 
  System.out.println(">>>" + taskNum + " Task start "); 
  Date dateTmp1 = new Date(); 
  Thread.sleep(1000); 
  Date dateTmp2 = new Date(); 
  long time = dateTmp2.getTime() - dateTmp1.getTime(); 
  System.out.println(">>>" + taskNum + " Task to terminate "); 
  return taskNum + " The task returns the result of the run , Current task time [ " + time + " Ms. "; 
} 
}

Code description:
Executors, in the code above provides a series of factory method used to pioneer the thread pool, returned to the thread pool implementation the ExecutorService interface.
Public static ExecutorService newFixedThreadPool(int nThreads)
Creates a thread pool with a fixed number of threads.
Public static ExecutorService newCachedThreadPool ()
Create a cacheable thread pool and call execute will reuse previously constructed threads (if threads are available). If no existing thread is available, a new thread is created and added to the pool. Terminates and removes threads from the cache that have not been used for 60 seconds.
Public static ExecutorService newSingleThreadExecutor ()
Create a single threaded Executor.
Public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
Create a thread pool that supports regular and periodic task execution, and in most cases can be used as an alternative to the Timer class.
ExecutoreService provides a submit() method, passes a Callable, or Runnable, and returns the Future. If the Executor background thread pool has not completed the computation of the Callable, this calls the get() method that returns the Future object, blocking until the computation is complete.

Summary: there are 2 ways to implement Java multithreading. Runable is the interface and thread is the class. Runnable only provides a run method. The third way is to listen to the brothers in the group, so baidu up.

The above is the entire content of this article, I hope to help you with your study.


Related articles: