java多线程
来源:互联网 发布:高校邦网络课程登录 编辑:程序博客网 时间:2024/06/06 01:35
java.util.concurrent包里提供了关于多线程操作的类,平常用的比较多的是ExecutorService及其实现类(如ThreadPoolExecutor等),Executor,Executors,Future,Callable等
1. ExecutorService(继承自Executor)接口:提供了一些异步的多线程操作方法,如execute(), submit(), shutdown(), shutdownNow()等
2. Executor接口:执行提交的任务(线程),只有一个方法 execute(Runnable a)
2. Executors类: 提供了一些工厂方法和一些公共方法来操作Executor子类和ThreadFactory等,如newXXX(),xxxThreadFactory()等
3. Futrue接口:代表了线程执行结果,提供了获取线程执行结果和取消线程的方法,如get(),cancle()等
4. Callable接口:JDK1.5提供的有返回值的线程执行新接口
对ExecutorService和Future的理解做简单记录
public class Main { 2 private static int count = 0; 3 4 public static void main(String[] args){ 5 List<Future> resultList = new LinkedList<>(); 6 7 /** 8 * Executors.newCachedThreadPool() 创建一个线程缓存池,若60s中线程没有被使用,则会停止线程并从缓存池中移除 9 * Executors.newScheduledThreadPool() 创建一个固定容量的线程池,里边的线程按照设定的调度时间执行10 * Executors.newFixedThreadPool() 拥有固定容量的线程缓存池11 * Executors.newSingleThreadExecutor() 容量为一的线程缓存池,只会有一个线程12 */13 ExecutorService executorService = Executors.newCachedThreadPool();14 for(int i=0; i<10; i++){15 Future future = executorService.submit(new Callable<String>() {16 @Override17 public String call() {18 try {19 System.out.println(Thread.currentThread().getName());20 Thread.sleep(5000);21 } catch (InterruptedException e) {22 e.printStackTrace();23 }24 int count = Main.count;25 System.out.println(Thread.currentThread().getName() + "..start Main count:..." + count);26 Main.count = ++count;27 System.out.println(Thread.currentThread().getName() + "..end Main count:..." + Main.count);28 return Thread.currentThread().getName();29 }30 });31 resultList.add(future);32 }33 executorService.shutdown();34 for(Future future: resultList){35 try {36 System.out.println(future.get() + "..is over...");37 } catch (InterruptedException e) {38 e.printStackTrace();39 } catch (ExecutionException e) {40 e.printStackTrace();41 }42 }43 System.out.println("main thread end...");44 }45 }
总结:
1. ExecutorService提供的execute()方法和submit()方法的区别:
a. execute()方法只接受Runnable类型的实例,所以不能拿到返回值,也不能动态获取线程执行的情况
b. submit()方法接受Runnable和Callable实例,会返回Future实例,Future实例的get()方法可以获取线程执行返回值,并能抛出线程执行异常。所以如果要获取线程执行返回的结果,并能处理线程执行时可能出现的异常,或者想中途取消线程执行时可以使用submit()方法
2. 通过输出可以看到main方法(主线程)在所有线程执行完成后结束,原因:
a. 通过submit()方法获取Future实例,并通过Future实例的get()方法获取线程返回结果,而Future实例的get()方法会等待线程执行完毕才会返回,所以main方法会等待所有子线程结束才会结束
b. 若去掉上边红色标注的for循环,则main方法(主线程)会提前结束,而不会等待所有子线程结束
补充:
1. 多个线程并发执行时,若其中某一个线程出现了异常并且没有被处理,则该线程会自动停止执行,但其他线程还是会正常执行,这就是为什么tomcat请求出现异常时,tomcat还可以继续提供服务的原因
2. tomcat提供了线程池和等待池,每一个请求过来都会重新启动一个新的线程处理该请求,若线程池中线程用完,再来请求的时候就会放到等待池中等待,当其中有线程释放回线程池中时,就会为等待池中的请求分配线程处理请求
ExecutorService对象的shutdown()和shutdownNow()的区别
可以关闭 ExecutorService,这将导致其拒绝新任务。提供两个方法来关闭 ExecutorService。shutdown() 方法在终止前允许执行以前提交的任务,而 shutdownNow() 方法阻止等待任务启动并试图停止当前正在执行的任务。在终止时,执行程序没有任务在执行,也没有任务在等待执行,并且无法提交新任务。应该关闭未使用的 ExecutorService 以允许回收其资源。
下列方法分两个阶段关闭 ExecutorService。第一阶段调用 shutdown 拒绝传入任务,然后调用 shutdownNow(如有必要)取消所有遗留的任务:
shutdown调用后,不可以再submit新的task,已经submit的将继续执行。
shutdownNow试图停止当前正执行的task,并返回尚未执行的task的list
下列方法分两个阶段关闭 ExecutorService。第一阶段调用 shutdown 拒绝传入任务,然后调用 shutdownNow(如有必要)取消所有遗留的任务:
shutdown调用后,不可以再submit新的task,已经submit的将继续执行。
shutdownNow试图停止当前正执行的task,并返回尚未执行的task的list
- 【Java多线程】多线程死锁
- Java 多线程
- java 多线程
- java多线程
- JAVA多线程
- java多线程
- JAVA多线程
- java多线程
- JAVA 多线程
- Java多线程
- java多线程
- JAVA 多线程
- Java 多线程
- Java 多线程
- java多线程
- Java 多线程
- Java多线程
- java 多线程
- spring框架(二)——spring概述与spring的核心之IOC
- Java main函数中的String[] args
- ZIP压缩算法详细分析及解压实例解释
- 分布式定时任务
- 数浪最难是起点
- java多线程
- 构造函数与析构函数
- RabbitMq3.6.12 (centos7)安装与基本使用
- 8.PHP 命令行下的世界
- 《坚持,一种可以养成的习惯》读书笔记
- 关于意志力,不得不说的十二件事
- 如何利用番茄工作法提高学习和工作的效率
- python中import和from import 的区别
- 关于如何读书,我们一起聊聊