目录
(1)提高用户体验或者避免ANR(Application is not responding)
(2)异步
在应用程序中,有些情况下并不一定需要同步阻塞去等待返回结果,可以通过多线程来实现异步,如异步加载云端图片
- class MyThread extends Thread{
- @Override
- public void run() {
- super.run();
- Log.e("TAG:",Thread.currentThread().getName()+".run");
- }
- }
- class MyRunnable implements Runnable{
-
- @Override
- public void run() {
- Log.e("TAG:",Thread.currentThread().getName()+".run");
- }
- }
- //创建线程
- class MyJob implements Callable{
-
- @Override
- public Boolean call() throws Exception {
- for (int i = 0; i < 5; i++) {
- System.out.println("I am running thread");
- }
- return true;
- }
- }
- //调用
-
- MyJob thread = new MyJob();
-
- // execute service,number of threads = 1
- ExecutorService service = Executors.newFixedThreadPool(1);
-
- // submit to execute
- Future
result = service.submit(thread); -
- boolean r = result.get(); // get result
-
- service.shutdownNow(); // shut down the service
-
- System.out.println(r);
- class MyTask implements Runnable{
- int index = 0;
- public MyTask(int i){this.index = i;}
- @Override
- public void run() {
- Log.e("TAG:",Thread.currentThread().getName()+" "+index);
- try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
- }
- }
-
-
- ExecutorService cacheThreadPool = Executors.newCachedThreadPool();
-
- ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
-
- ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
-
- ScheduledExecutorService scheduledExecutorService =
-
- Executors.newSingleThreadScheduledExecutor();
-
- for(int i=1;i<=100;i++){
-
- singleThreadPool.execute(new MyTask(i));
-
- }

(1)new Thread的弊端
a)每次new Thread新建对象性能差
b)线程缺乏统一管理,可能无限制新建线程,相互竞争,可能占用过多系统资源导致死机或内存溢出oom
c)缺乏更多功能,如定时执行、定期执行、线程中断
(2)线程池好处
a)重用存在的线程,减少对象创建、消亡的开销,性能佳
b)可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞
c)提供定时执行、定期执行、单线程、并发数控制等功能
1:ThreadPoolExecutor 基本线程池
2:FixedThreadPool (执行长期的任务,性能好很多)
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3:CachedThreadPool (适用于有大量需要立即执行的耗时少的任务的情况)
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
4:SingleThreadPool(一个任务一个任务执行的场景是的单个的FixedThreadPool )
创建一个单线程化的线程池,只会用唯一的工作线程来执行任务,保证所有任务按照指定的顺序(FIFO LIFO 优先级)执行。
5:ScheduledThreadPool(周期性执行任务的场景)
创建一个定长线程池,支持定时、周期性任务执行。
1,新建线程池
- //创建基本线程池
- final ThreadPoolExecutor threadPoolExecutor = new
- ThreadPoolExecutor(3,5,1,TimeUnit.SECONDS,
- new LinkedBlockingQueue
(100)); -
- /*创建fixed线程池,参数为核心线程数,
- 只有核心线程,无非核心线程,并且阻塞队列无界。
- 采用LinkedBlockingQueue
- */
- final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
-
- /*创建Cached线程池,没有核心线程,
- 只有非核心线程,并且每个非核心线程空闲等待的时间为60s,
- 采用SynchronousQueue队列。
- */
- final ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
-
- /*创建Single线程池,只有一个核心线程,当被占用时,
- 其他的任务需要进入队列等待,采用LinkedBlockingQueue
- */
- final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
-
- /*创建Scheduled线程池,延迟启动任务,
- 使用方法scheduledThreadPool.(runnable,10,TimeUnit.SECONDS);
- */
- final ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
2 加入线程,几种线程池的使用方法都一样,除了ScheduledExecutorService ;
- threadPoolExecutor.execute(new Runnable() {
- @Override
- public void run() {
- try {
- //处理相应事务
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- });
ScheduledExecutorService 使用方法
- //10是指延时10s启动
- scheduledThreadPool.(runnable,10,TimeUnit.SECONDS);
3 其他方法
- 1.shutDown() 关闭线程池,不影响已经提交的任务
-
- 2.shutDownNow() 关闭线程池,并尝试去终止正在执行的线程
-
- 3.allowCoreThreadTimeOut(boolean value) 允许核心线程闲置超时时被回收
-
- 4.submit 一般情况下我们使用execute来提交任务,但是有时候可能也会用到submit,使用submit的好处是submit有返回值。
-
- 5.beforeExecute() - 任务执行前执行的方法
-
- 6.afterExecute() -任务执行结束后执行的方法
-
- 7.terminated() -线程池关闭后执行的方法