Four ways to implement JAVA multi-threading - Java multi-thread concurrency with return value

JAVA多线程实现的四种方式
Java多线程实现方式主要有四种:继承Thread类、实现Runnable接口、
实现Callable接口通过FutureTask包装器来创建Thread线程、
使用ExecutorService、Callable、Future实现有返回结果的多线程。
其中前两种方式线程执行完后都没有返回值,后两种是带返回值的。

1. Inherit the Thread class to create a thread

The Thread class is essentially an instance that implements the Runnable interface and represents an instance of a thread. The only way to start a thread is through the start() instance method of the Thread class. The start() method is a native method that will start a new thread and execute the run() method. It is very simple to implement multi-threading in this way. By directly extending Thread through your own class and overriding the run() method, you can start a new thread and execute your own defined run() method. For example:

publicclass MyThread extends Thread {  
  publicvoid run() {  
   System.out.println("MyThread.run()");  
  }  
}  

MyThread myThread1 = new MyThread();  
MyThread myThread2 = new MyThread();  
myThread1.start();  
myThread2.start();  

2. Implement the Runnable interface to create threads

If your class has extended another class, you cannot extend Thread directly. At this time, you can implement a Runnable interface, as follows:

In order to start MyThread, you need to first instantiate a Thread and pass in your own MyThread instance:

In fact, when a Runnable target parameter is passed to Thread, Thread's run() method will call target.run()

3. Implement the Callable interface to create Thread threads through the FutureTask wrapper

The Callable interface (which also has only one method) is defined as follows:

publicinterface Callable   { 
  V call() throws Exception;   } 

publicclass SomeCallable extends OtherClass implements Callable {

    @Override
    public V call() throws Exception {
        // TODO Auto-generated method stubreturnnull;
    }

}

Callable oneCallable = new SomeCallable();   
//由Callable创建一个FutureTask对象:   
FutureTask oneTask = new FutureTask(oneCallable);   
//注释:FutureTask是一个包装器,它通过接受Callable来创建,它同时实现了Future和Runnable接口。 
  //由FutureTask创建一个Thread对象:   
Thread oneThread = new Thread(oneTask);   oneThread.start();   
//至此,一个线程就创建完成了。

4. Use ExecutorService, Callable, and Future to implement threads that return results

The three interfaces ExecutorService, Callable, and Future actually belong to the Executor framework. The thread that returns the result is a new feature introduced in JDK1.5. With this feature, you no longer need to go through a lot of trouble to get the return value. And even if you implement it yourself, it may be full of loopholes.

Tasks that can return values ​​must implement the Callable interface. Similarly, tasks that do not return a value must implement the Runnable interface.

After executing the Callable task, you can obtain a Future object, and call get on the object to obtain the Object returned by the Callable task.

Note: The get method is blocking, that is: the thread returns no result, and the get method will wait forever.

Combined with the thread pool interface ExecutorService, the legendary multi-threading with returned results can be realized.

5. Provide an example of concurrency and return that you run.

A complete multi-thread test example with returned results. It has been verified under JDK1.5 and can be used directly without any problems. code show as below:

package com.thread.future;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * 
 * ClassName: TestThread <br/>
 * Function: 测试并发的有返回值的例子. <br/>
 * Reason: TODO ADD REASON(可选). <br/>
 * date: 2017年5月27日 上午11:10:43 <br/>
 *
 * @author lichch
 * @version
 * @since JDK 1.7
 */
@SuppressWarnings("unchecked")
public class TestThread {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("----程序开始运行----");
        Date date1 = new Date();

        int taskSize = 5;

        // 创建一个线程池
        ExecutorService pool = Executors.newFixedThreadPool(taskSize);

        // 创建多个有返回值的任务
        List<Future> list = new ArrayList();

        for (int i = 0; i < taskSize; i++) {
            Callable c = new MyCallable(i + " ");

            // 执行任务并获取Future对象
            Future f = pool.submit(c);

            // 单个查询返回的Future
            System.out.println(">>>" + f.get().toString());
            list.add(f);
        }

        // 关闭线程池
        pool.shutdown();

        // 获取所有并发任务的运行结果
        for (Future f : list) {

            // 从Future对象上获取任务的返回值,并输出到控制台
            System.out.println(">>>" + f.get().toString());
        }

        Date date2 = new Date();
        System.out.println("----程序结束运行----,程序运行时间【" + (date2.getTime() - date1.getTime()) + "毫秒】");
    }
}

class MyCallable implements Callable {
    private String taskNum;

    MyCallable(String taskNum) {

        this.taskNum = taskNum;
    }

    public Object call() throws Exception {
        System.out.println(">>>" + taskNum + "任务启动");
        Date dateTmp1 = new Date();
        Thread.sleep(1000);
        Date dateTmp2 = new Date();

        long time = dateTmp2.getTime() - dateTmp1.getTime();
        System.out.println(">>>" + taskNum + "任务终止");

        return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】";
    }
}

The Executors class in the above code provides a series of factory methods for creating thread pools, and the returned thread pools all implement the ExecutorService interface.
public static ExecutorService newFixedThreadPool(int nThreads)
Create a thread pool with a fixed number of threads.
public static ExecutorService newCachedThreadPool()
Create a cacheable thread pool, calling execute will reuse the previously constructed thread (if the thread is available). If no existing thread is available, a new thread is created and added to the pool. Terminate and remove from the cache those threads 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 scheduled and periodic task execution, which can be used to replace the Timer class in most cases.
ExecutoreService provides the submit() method, passing a Callable or Runnable and returning a Future. If the Executor background thread pool has not completed the calculation of Callable, this call returns the get() method of the Future object, which will block until the calculation is completed.

Guess you like

Origin blog.csdn.net/qq_42857603/article/details/107303842