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,感谢作者分享!