Android进阶之线程池
来源:互联网 发布:linux 用户安全设置 编辑:程序博客网 时间:2024/06/05 17:17
一,原理
线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。
比如:一个应用要和网络打交道,有很多步骤需要访问网络,为了不阻塞主线程,每个步骤都创建个线程,在线程中和网络交互,用线程池就变的简单,线程池是对 线程的一种封装,让线程用起来更加简便,只需要创一个线程池,把这些步骤像任务一样放进线程池,在程序销毁时只要调用线程池的销毁函数即可。
二,java中四种线程池
newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
package test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolExecutorTest { public static void main(String[] args) { ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { final int index = i; try { Thread.sleep(index * 1000); } catch (InterruptedException e) { e.printStackTrace(); } cachedThreadPool.execute(new Runnable() { public void run() { System.out.println(index); } }); } } }
- newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
package test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolExecutorTest { public static void main(String[] args) { ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); for (int i = 0; i < 10; i++) { final int index = i; fixedThreadPool.execute(new Runnable() { public void run() { try { System.out.println(index); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } } }
因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字。
定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()
- newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行
package test; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ThreadPoolExecutorTest { public static void main(String[] args) { ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); scheduledThreadPool.schedule(new Runnable() { public void run() { System.out.println("delay 3 seconds"); } }, 3, TimeUnit.SECONDS); } }
表示延迟1秒后每3秒执行一次。
- newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
package test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolExecutorTest { public static void main(String[] args) { ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); for (int i = 0; i < 10; i++) { final int index = i; singleThreadExecutor.execute(new Runnable() { public void run() { try { System.out.println(index); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } }
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
三,自定义线程池
1.ThreadPoolExecutor
基础API的介绍
- isShutdown() : 判断线程池是否关闭
- isTerminated() : 判断线程池中任务是否执行完成
- shutdown() : 调用后不再接收新任务,如果里面有任务,就执行完
- shutdownNow() : 调用后不再接受新任务,如果有等待任务,移出队列;有正在执行的,尝试停止之
- submit() : 提交执行任务
- execute() : 执行任务
- 构造函数相关的介绍
- corePoolSize : 核心工作的线程个数
- maximumPoolSize : 最大线程个数
- keepAliveTime : 额外线程空闲的时间
- unit : keepAliveTime的单位
- workQueue : 任务队列参考BlockingQueue
- threadFactory : 线程工厂,如何去创建线程的
2.阻塞队列的介绍(BlockingQueue)
阻塞队列,如果BlockingQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态,直到BlockingQueue进了东西才会被唤醒,同样,如果BlockingQueue是满的,任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有空间时才会被唤醒继续操作。
基础API介绍
往队列中加元素的方法
- add(E) : 非阻塞方法, 把元素加到BlockingQueue里,如果BlockingQueue可以容纳,则返回true,否则抛出异常。
- offer(E) : 非阻塞, 表示如果可能的话,将元素加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false。
- put(E):阻塞方法, 把元素加到BlockingQueue里,如果BlockingQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里有空间再继续。
从队列中取元素的方法
- poll(time): 阻塞方法,取走BlockingQueue里排在首位的元素,若不能立即取出,则可以等time参数规定的时间,取不到时返回null。
- take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的对象被加入为止。
子类介绍
ArrayBlockingQueue : FIFO 队列,规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小
LinkedBlockingQueue:FIFO 队列,大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定。
PriorityBlockingQueue:优先级队列, 类似于LinkedBlockingQueue,但队列中元素非 FIFO, 依据对象的自然排序顺序或者是构造函数所带的Comparator决定的顺序
SynchronousQueue: 交替队列,队列中操作时必须是先放进去,接着取出来,交替着去处理元素的添加和移除
3. RejectedExecutionHandler介绍
实现的子类介绍
ThreadPoolExecutor.AbortPolicy
当添加任务出错时的策略捕获器,如果出现错误,则直接抛出异常
ThreadPoolExecutor.CallerRunsPolicy
当添加任务出错时的策略捕获器,如果出现错误,直接执行加入的任务
ThreadPoolExecutor.DiscardOldestPolicy
当添加任务出错时的策略捕获器,如果出现错误,移除第一个任务,执行加入的任务
ThreadPoolExecutor.DiscardPolicy
当添加任务出错时的策略捕获器,如果出现错误,不做处理
四,类图
- Android进阶之线程池
- Android进阶-线程池
- Android进阶—线程池
- 线程精进指南之线程池进阶
- Java进阶之线程池AsyncTask
- Android进阶——多线程系列之四大线程池的使用介绍
- Android开发进阶—线程和线程池
- Java线程之进阶篇
- Android之线程池
- Android之线程池
- android之线程池
- android之线程池
- 【Java进阶】Java多线程之线程池浅析
- 【Android框架进阶〖02〗】ThinkAndroid线程池机制
- Android进阶之引用
- Android之ListView进阶
- android进阶之spinner
- android进阶之GridView
- ECMAScript 6 学习笔记
- 算法——从旋转字符串到翻转单词
- JNI的使用和注意事项
- javascript
- php:正则表达式的基本语法
- Android进阶之线程池
- 实现自己的EventBus
- 如何求二进制表示中“1”的个数
- Android使用xml旋转图片,个人记录
- Apache commons (Java常用工具包)简介
- 控制台五子棋游戏类记录
- 导入v4库源码
- leetcode012 Integer to Roman
- 自定义view之一:自定义验证码控件