阻塞式和定时式那种获取任务方式更好?
Future获取结果的方式有两种
一个是无参的get方法,另一个是有参的get方法 总结 取消任务的cancel方法的一些困惑
cancel(boolean) 取消任务
true:表示尝试中断正在执行任务的线程(只对执行中的任务有意义)
取消正在执行的任务 false:则相反
取消未执行任务取消已完成任务 总结 参考地址
阻塞式和定时式那种获取任务方式更好? Future获取结果的方式有两种 一个是无参的get方法,它是阻塞式的,获取结果会一直等到结果输出。案例如下:先创建任务类
import java.util.concurrent.Callable; public class ResultTask implements Callable{ public Integer call() throws Exception { return 1+1; } }
然后创建单个线程池获取任务结果
import com.naidou.threadPool.tp04.ResultTask;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadPool05 {
public static void main(String[] args) {
// 创建任务
com.naidou.threadPool.tp04.ResultTask task = new ResultTask();
// 创建单个线程的线程池
ExecutorService threadPool = Executors.newSingleThreadExecutor();
// 提交任务
Future future = threadPool.submit(task);
try {
// 获取任务执行结果
Integer result = future.get();
// 输出任务执行结果
System.out.println(result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
// 关闭线程池
threadPool.shutdown();
}
}
}
输出结果:程序正常输出
另一个是有参的get方法
我们可以设置获取结果的超时时间,如果大于超时时间,那么程序会抛出TimeoutException异常
案例如下:先创建任务类,设置线程休眠时间为3秒
import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; public class ResultTask01 implements Callable{ public Integer call() throws Exception { // 使当前线程休眠3秒钟 TimeUnit.SECONDS.sleep(3); return 1+1; } }
然后创建单个线程获取任务,先设置获取结果超时时间为1秒
import java.util.concurrent.*;
public class ThreadPool051 {
public static void main(String[] args) {
// 创建任务
ResultTask01 task = new ResultTask01();
// 创建单个线程的线程池
ExecutorService threadPool = Executors.newSingleThreadExecutor();
// 提交任务
Future future = threadPool.submit(task);
try {
// 获取任务执行结果
Integer result = future.get(1,TimeUnit.SECONDS);
// 输出任务执行结果
System.out.println(result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
} finally {
// 关闭线程池
threadPool.shutdown();
}
}
}
输出结果:抛出超时异常,符合预期
然后设置超时时间为5秒
// 获取任务执行结果
Integer result = future.get(5,TimeUnit.SECONDS);
输出结果:3秒后程序正常输出,符合预期
总结
两种写法都可以,依据不同业务视情况而定,一般用无参方法比较多。 取消任务的cancel方法的一些困惑 cancel(boolean) 取消任务 true:表示尝试中断正在执行任务的线程(只对执行中的任务有意义) 取消正在执行的任务
创建任务类
import java.util.concurrent.Callable; public class ResultTask042 implements Callable{ public Integer call() throws Exception { // 计数器 int i = 0; // 当线程没被中断时 while (!Thread.interrupted()){ // 递增i i++; } // 输出i System.out.println("i的值:"+i); // 返回1+1的值 return 1+1; } }
线程取消正在执行任务
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadPool042 {
public static void main(String[] args) {
// 创建任务
ResultTask task = new ResultTask();
// 创建单个线程的线程池
ExecutorService threadPool = Executors.newSingleThreadExecutor();
// 提交任务
Future future = threadPool.submit(task);
System.out.println("任务是否完成:" + future.isDone());
// 取消任务 调用interrupt打断
boolean cancel = future.cancel(true);
System.out.println("任务是否取消成功:" + cancel);
System.out.println("任务是否取消:" + future.isCancelled());
try {
// 获取任务执行结果
Integer result = future.get();
// 输出任务执行结果
System.out.println(result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
// 关闭线程池
threadPool.shutdown();
}
}
}
输出结果:任务取消成功,并引发CancellationException 异常
false:则相反
取消未执行任务
创建任务类
import java.util.concurrent.Callable; public class ResultTask implements Callable{ public Integer call() throws Exception { return 1+1; } }
取消未执行任务
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadPool04 {
public static void main(String[] args) {
// 创建任务
ResultTask task = new ResultTask();
// 创建单个线程的线程池
ExecutorService threadPool = Executors.newSingleThreadExecutor();
// 提交任务
Future future1 = threadPool.submit(task);
Future future2 = threadPool.submit(task);
// 取消任务 调用interrupt打断 取消未执行任务
boolean cancel = future2.cancel(false);
System.out.println("任务是否取消成功:" + cancel);
System.out.println("任务是否取消:" + future2.isCancelled());
try {
// 获取任务执行结果
Integer result = future2.get();
// 输出任务执行结果
System.out.println(result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
// 关闭线程池
threadPool.shutdown();
}
}
输出结果:任务取消成功,获取结果引发CancellationException 异常
取消已完成任务
尝试取消已完成任务
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadPool041 {
public static void main(String[] args) {
// 创建任务
ResultTask task = new ResultTask();
// 创建单个线程的线程池
ExecutorService threadPool = Executors.newSingleThreadExecutor();
// 提交任务
Future future = threadPool.submit(task);
try {
// 获取任务执行结果
Integer result = future.get();
// 输出任务执行结果
System.out.println(result);
// 取消任务 调用interrupt打断 取消未执行任务
boolean cancel = future.cancel(false);
System.out.println("任务是否取消成功:" + cancel);
System.out.println("任务是否取消:" + future.isCancelled());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
// 关闭线程池
threadPool.shutdown();
}
}
}
输出结果:已完成任务无法取消
总结
线程池视频讲解05,06



