Java多线程之Callable、Future、FutureTask

package Thread;

import java.util.Scanner;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

/**
 * 使用Thread和Runable都可以创建线程,但是都没有返回值。JDK1.5之后,java 推出了 Callable,使用带有泛型参数
 * 的Callable对象,可以返回线程执行后的结果。大多数情况下,Callable配合ExecutorService使用。或者
 * 、
 * Callable,FutureTask,ExecutorService三者一起使用。
 * 
 * 
 * 
 * 
 * ExecutorService的submit方法有三种重载形式,分别为:
 *  1.<T> Future<T> submit(Callable<T> c);
 *  2.<T> Future<T> submit(Runnable r,T Result);
 *  3.Future<?> submit(Runnable r);
 *  其中,第一种和第三种重载方法使用最多。
 *  
 *  FutureTask是Runnable和Callable的子类,所以ExecutorService的submit方法的参数可以直接是
 *  FutureTask对象。
 *  FutureTask有两个构造方法,一个是 FutureTask(Callable<V> callable),
 *  另一个是 FutureTask(Runnable runnable, V result),其中result是创建FutureTask时设置的,
 * 
 */

/**
 * FutureTask 继承于Runnable和uture。因此 ExecutorService的submit中可以使用FutureTask作为参数
 */
public class FutureRunnableTest {

	 static ExecutorService executorService = Executors.newCachedThreadPool();
	
	public static void main(String[] args) {
		f4();
	}
	
	// ExecutorService+Future +Callable
	static void f1(){
		Future<Integer> future=executorService.submit(new MyCallable());
		
		/**
		 * 调用shutdown方法关闭线程池,调用shutdown方法之后所有线程执行结束后线程池关闭。
		 * 所以在使用线程池的时候如果是方法内部使用一定要shutdown销毁线程,如果是全局使用的静态线程池可以不shutdown
		 * 
		 * 而shutdownNow会强行关闭线程池,正在执行的线程也会被尝试销毁。
		 * awaitTermination方法一般在shutdown访法之后,阻塞直到线程池中所有任务执行结束。
		 */
		executorService.shutdown();
		
		try {
			System.err.println("future获取到的值为:"+future.get());
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	
	
	//ExecutorService+FutureTask+Callable
	static void f2(){
		
		MyCallable myCallable=new MyCallable();
		FutureTask<Integer> futureTask=new FutureTask<Integer>(myCallable);
		executorService.submit(futureTask);
		executorService.shutdown();
		try {
			System.err.println("futureTask获取到的值为:"+futureTask.get());
			System.err.println("futureTask执行是否结束:"+futureTask.isDone());
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	
	//ExecutorService+FutureTask+Runnable(感觉没太大意义)
	static void f3(){
		MyRunable myRunable=new MyRunable();
		//使用Runable作为FutureTask的参数时,需设置result的值(似乎没太大意义)
		FutureTask<Integer> futureTask=new FutureTask<Integer>(myRunable,55);
		executorService.submit(futureTask);
		executorService.shutdown();
		
		try {
			//执行结果:futureTask执行是否结束:false
			System.err.println("futureTask执行是否结束:"+futureTask.isDone());
			//执行结果futureTask获取到的值为:55
			System.err.println("futureTask获取到的值为:"+futureTask.get());
		} catch (Exception e) {
			e.printStackTrace();
		} 
		
	}
	
	//Thread+FutureTask+Callable(Runable)
	//因为FutureTask是Runable的实现类,可以直接使用Thread构建线程程
	static void f4(){
		MyCallable myCallable=new MyCallable();
		FutureTask<Integer> futureTask=new FutureTask<Integer>(myCallable);
		/**
		 * 或者使用Runnable构建FutureTask者
		 * MyRunable myRunable=new MyRunable();
		   FutureTask<Integer> futureTask=new FutureTask<Integer>(myRunable,55);
		 */

		Thread thread=new Thread(futureTask);
		thread.start();
		
		try {
			System.err.println("futureTask获取到的值为:"+futureTask.get());
			System.err.println("futureTask执行是否结束:"+futureTask.isDone());
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}

}

  class MyCallable implements Callable<Integer>{


	public Integer call() throws Exception {
		int sum=0;
		int num=1000;
		for(int i=0;i<=num;i++){
			sum=sum+i;
		}
		
		return sum;
	}}
  
  class MyRunable implements Runnable{

	@Override
	public void run() {
		try {
			Thread.sleep(200);
			
			System.err.println(Thread.currentThread().getName()+" 线程执行结束");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	  
  }

参考连接:https://blog.csdn.net/predisw/article/details/49094177,感谢作者分享!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章