博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅谈篇之线程池
阅读量:3963 次
发布时间:2019-05-24

本文共 2576 字,大约阅读时间需要 8 分钟。

一、线程池

线程池的出现是为了尽量地压榨cpu的性能。
1、使用线程池的好处
第一,提高应用程序的响应速度,池中的线程都是提前创建好的,当任务到达时,只需要把任务交给线程执行就可以了,避免反复创建线程反复与内核打交道的耗时操作。
第二,可以节省程序所使用的资源,如果每一个任务到来都要分别为它们创建线程,势必造成线程的数量过多,每个线程大约占用1M内存,可以在线程池创建有限数量的线程,让这些线程轮流不间断地执行任务。
第三,可以在任务和线程执行之间创建一种缓冲,在任务量大时,所有的任务都能够按序完成而不会发生践踏。
2、java中线程池的结构模型
在这里插入图片描述

3、java的线程池框架

在这里插入图片描述

4、如何使用线程池

要得到一个线程池的对象,创建的过程比较麻烦,java专门提供了一个线程喷池工具类来完成不同种类线程池的创建。
1、创建具有固定数量线程的线程池,适用场合在于任务极大

ExecutorService executor = Executors.newFixedThreadPool(2);//池中有两个线程public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue
());}

nThreads:表示池中核心线程的数量,永远不会消失。

nThreads:表示池中最大的线程数量,当核心线程都在工作是可以再创建新的线程,但总数量不能超过该值,非核心线程当任务完成经过规定超时就会消失
0L: 超时时间,非核心线程执行完毕马上消失
TimeUnit.MILLISECONDS, 超时的时间单位
LinkedBlockingQueue 链表结构的阻塞队列,所有的任务 先进入队列再分配给池中的线程.

ExecutorService executor = Executors.newFixedThreadPool(2);for (int i = 0; i <20 ; i++) {
//在内部类中使用外部类方法中的局部变量,为了保证该变量值的稳定性, // 要防止该值被外部和内部类同时修改,所以必须在声明时加上final防止值被改变 final int j = i; executor.submit( new Runnable() {
@Override public void run() {
try {
Thread.currentThread().sleep(20); } catch (InterruptedException e) {
e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"执行任务"+j); } } );}//停止线程池,在很多应用是不需要的//executor.shutdownNow();//当前池中有未执行完的任务会被强行终止executor.shutdown();//等待队列中的线程都执行完毕再终止

5、如何通过线程池让任务具有返回值

有时候,需要线程在执行完毕后返回一个结果,可java的线程的run()并没有返回值也不能抛出异常,那么基于线程池可以改变以上的情况。

ArrayList
> results = new ArrayList<>(); ExecutorService executor = Executors.newFixedThreadPool(2); for (int i = 0; i < 20; i++) {
Future
future = executor.submit(new Task(i));//不会阻塞 results.add(future); } //呈现各任务的执行结果 for (Future
f:results) {
try {
System.out.println(f.get()); } catch (InterruptedException e) {
e.printStackTrace(); } catch (ExecutionException e) {
e.printStackTrace(); } } }}
class Task implements Callable{
//该类的对象可作为线程池的任务 int num; public Task(int num) {
this.num = num; } @Override public Object call() throws Exception {
Thread.currentThread().sleep(1000); return 2*num; }}

转载地址:http://qzzki.baihongyu.com/

你可能感兴趣的文章
去掉文件名中的路径
查看>>
Spring Batch Step 流程
查看>>
动态代理
查看>>
如何写出高效的正则表达式
查看>>
多个 ZooKeeper 服务器的例子
查看>>
正则表达式
查看>>
Java I/O
查看>>
序列化
查看>>
Perl 精萃
查看>>
Perl 简介
查看>>
Perl 注释
查看>>
数据类型之标量
查看>>
调试 Perl 脚本
查看>>
增强的for循环语句
查看>>
方法的可变参数
查看>>
静态导入
查看>>
java 泛型
查看>>
控制结构
查看>>
标准输入输出
查看>>
运算符
查看>>