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