实现Callable接口

从Java5开始新增加创建线程的第三种方式为实现java.util.concurrent.Callable接口。

常用的方法如下:

方法声明 功能介绍
V call() 计算结果并返回
  1. package com.lagou.task18;
  2. import java.util.concurrent.Callable;
  3. import java.util.concurrent.ExecutionException;
  4. import java.util.concurrent.FutureTask;
  5. /**
  6. * @author lijing
  7. * @date 2020/10/15 16:32
  8. * @description
  9. */
  10. public class ThreadCallableTest implements Callable {
  11. @Override
  12. public Object call() throws Exception {
  13. //计算1~10000之间的累加和并打印
  14. int sum=0;
  15. for (int i = 1; i <= 10000; i++) {
  16. sum+=i;
  17. }
  18. System.out.println("计算的累加和是:"+sum);
  19. return sum;//自动装箱
  20. }
  21. public static void main(String[] args){
  22. ThreadCallableTest tct=new ThreadCallableTest();
  23. FutureTask ft=new FutureTask(tct);
  24. Thread t1=new Thread(ft);
  25. t1.start();
  26. Object obj=null;
  27. try {
  28. obj = ft.get();
  29. } catch (InterruptedException e) {
  30. e.printStackTrace();
  31. } catch (ExecutionException e) {
  32. e.printStackTrace();
  33. }
  34. System.out.println("线程处理犯法的返回值是:"+obj);
  35. }
  36. }

FutureTask类

java.util.concurrent.FutureTask类用于描述可取消的异步计算,该类提供了Future接口的基本实现,包括启动和取消计算、查询计算是否完成以及检索计算结果的方法,也可以用于获取方法调用后的返回结果。
常用的方法如下:

FutureTask(Callable callable) 根据参数指定的引用来创建一个未来任务
V get() 获取call方法计算的结果

线程池的由来

在服务器编程模型的原理,每一个客户端连接用一个单独的线程为之服务,当与客户端的会话结束时,线程也就结束了,即每来一个客户端连接,服务器端就要创建一个新线程。
如果访问服务器的客户端很多,那么服务器要不断地创建和销毁线程,这将严重影响服务器的性能。

概念和原理

线程池的概念:首先创建一些线程,它们的集合称为线程池,当服务器接受到一个客户请求后,就从线程池中取出一个空闲的线程为之服务,服务完后不关闭该线程,而是将该线程还回到线程池中。
在线程池的编程模式下,任务是提交给整个线程池,而不是直接交给某个线程,线程池在拿到任务后,它就在内部找有无空闲的线程,再把任务交给内部某个空闲的线程,任务是提交给整个线程池,一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。

相关类和方法

从Java5开始提供了线程池的相关类和接口:java.util.concurrent.Executors类java.util.concurrent.ExecutorService接口。
其中Executors是个工具类和线程池的工厂类,可以创建并返回不同类型的线程池,常用方法如
下:

static ExecutorService newCachedThreadPool() 创建一个可根据需要创建新线程的线程池
static ExecutorService newFixedThreadPool(int
nThreads)
创建一个可重用固定线程数的线程池
static ExecutorService newSingleThreadExecutor() 创建一个只有一个线程的线程池

其中ExecutorService接口是真正的线程池接口,主要实现类是ThreadPoolExecutor,常用方法
如下:

void execute(Runnable command) 执行任务和命令,通常用于执行Runnable
Future submit(Callable task) 执行任务和命令,通常用于执行Callable
void shutdown() 启动有序关闭
  1. package com.lagou.task18;
  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.Executors;
  4. /**
  5. * @author lijing
  6. * @date 2020/10/15 16:39
  7. * @description
  8. */
  9. public class ThreadPoolTest {
  10. public static void main(String[] args) {
  11. //1.创建一个线程池
  12. ExecutorService executorService= Executors.newFixedThreadPool(10);
  13. //2.向线程池中布置任务
  14. executorService.submit(new ThreadCallableTest());
  15. //3.关闭线程池
  16. }
  17. }