java 线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用。

转载请声明出处谢谢!http://www.cnblogs.com/linguanh/

这里主要使用Executors中的4种静态创建线程池实例方法中的 newFixedThreadPool()来举例讲解。

简单说下Executors类,提供的一系列创建线程池的方法:

他们都有两个构造方法

1. --------newFixedThreadPool

(创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。)

public static ExecutorService newFixedThreadPool(int nThreads);
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory);

2. --------newSingleThreadExecutor

(创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。)

public static ExecutorService newSingleThreadExecutor();
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory);

3. --------newCachedThreadPool

(创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程)
public static ExecutorService newCachedThreadPool();
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory);

4. --------newScheduledThreadPool

创建一个定长线程池,支持定时及周期性任务执行。)

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize);
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory);

*******************************************

定长线程池-newFixedThreadPool 的第一个构造方法

public static ExecutorService newFixedThreadPool(int nThreads);传入的参数nThreads是最大的同时进行、并发的线程数。如果我定义它是3,那么同时执行3个,超过的了就要排队等待,流水线操作形式。

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory);

这个构造函数的第一个参数和上面的一个样,第二个是线程工厂,它的作用:

文档中是这样说的:

这是什么意思呢? 其实就是说,在把线程加入线程池之前,都对它们共同进行一些操作,例如改变一些属性。比如说setName(),thread-1和2、3、4 依次通过一个for 循环加入到线程池 中,他们的 Name 都会被改变。

线程池一般的使用方法:

通过 Executors.newFixedThreadPool(...).execute(Runnable()) 并发运行,例如下面的代码片段

 1 ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
 2 for (int i = 0; i < 10; i++) {
 3     final int index = i;
 4     fixedThreadPool.execute(new Runnable() {
 5
 6         @Override
 7         public void run() {
 8             try {
 9                 Log.d("******", Thread.currentThread().getId() + "  thread name: " + Thread.currentThread().getName()+"--"+index);
10                 Thread.sleep(2000);
11             } catch (InterruptedException e) {
12                 // TODO Auto-generated catch block
13                 e.printStackTrace();
14             }
15         }
16     });
17 }

运行结果如下

因为线程池大小为3,最多3个同时运行,每个输出index后sleep 2秒,所以每两秒打印3个数字。

线程池和AsyncTask()结合使用:

AsyncTask() 知识恶补入口:http://www.2cto.com/kf/201203/122729.html

这里只说下 AsyncTask()的executeOnExecutor() 方法,它是3.0后新增的一个方法。executeOnExecutor(Executor exec, Object... params),

该方法接受2个参数:

第一个参数是Executor,即是我们的线程池实例,默认的可以传入AsyncTask.THREAD_POOL_EXECUTOR,多线程并发,我们上面的是自定义的线程池,默认的最大并发5个,队列最大128个,当然,我们可以new 一个ThreadPoolExecutor 实例,通过传入参数改变这些限制;

第二个是任务参数。即是AsyncTask()中的第一个参数,我们可以在doInBackground()中获取它,我下面的例子中,这个参数是字符串。

下面通过运行代码看看它和 AsyncTask() 是怎样联系的:

  1 package cn.mr.ams.threadpool;
  2
  3 import android.app.Activity;
  4 import android.os.AsyncTask;
  5 import android.os.Bundle;
  6 import android.util.Log;
  7 import android.view.Menu;
  8 import android.view.MenuItem;
  9
 10 import java.util.concurrent.CyclicBarrier;
 11 import java.util.concurrent.ExecutorService;
 12 import java.util.concurrent.Executors;
 13 import java.util.concurrent.ThreadFactory;
 14
 15
 16 public class MyActivity extends Activity {
 17
 18     CyclicBarrier barrier = new CyclicBarrier(3);
 19     public static int j = 0 ;
 20     public final Object myTPLock = new Object();//对象锁,主要用来实现同步,我这里并没有使用
 21     public static ExecutorService myTP = null;//和 AsyncTask() 连用
 22     public static ExecutorService myTP_1 = Executors.newFixedThreadPool(3);//第一种构造函数
 23     //private List<String> test = new ArrayList<String>();
 24
 25     private String[] test = new String[]{"a--","b--","c--","d--","e--"};
 26
 27     @Override
 28     protected void onCreate(Bundle savedInstanceState) {
 29         super.onCreate(savedInstanceState);
 30         setContentView(R.layout.activity_my);
 31         //采用 第二种 构造方法,改写下 线程工厂 对象,使每次加入线程池中的线程都能被设置定义的属性
 32         myTP = Executors.newFixedThreadPool(3, new ThreadFactory() {
 33             @Override
 34             public Thread newThread(Runnable r) {
 35                 Thread t = new Thread(r);
 36                 //我把所加入到改线程池的线程全改名了
 37                 t.setName("LinGuanHong");
 38                 // 设置线程的优先级别
 39                 t.setPriority(Thread.NORM_PRIORITY - 1);
 40                 return t;
 41             }
 42         });
 43         for(String item : test) {
 44             //通过 for 循环,把 AsyncTask() 异步线程逐个 加入到线程池中
 45             new myThread(barrier).executeOnExecutor(myTP,item);
 46             //SystemClock.sleep(10);//能起到一定的延时,实现按顺序进行
 47         }
 48         /*for (int i = 0; i < 10; i++) {
 49             final int index = i;
 50             myTP_1.execute(new Runnable() {
 51                 @Override
 52                 public void run() {
 53                     try {
 54                         Log.d("******", Thread.currentThread().getId() + "  thread name: " + Thread.currentThread().getName()+"--"+index);
 55                         Thread.sleep(2000);
 56                     } catch (InterruptedException e) {
 57                         // TODO Auto-generated catch block
 58                         e.printStackTrace();
 59                     }
 60                 }
 61             });
 62         }*/
 63
 64     }
 65
 66
 67 public class myThread extends AsyncTask<Object, Void, String> {
 68     private CyclicBarrier barrier = null;
 69     public myThread(CyclicBarrier barrier){
 70         this.barrier = barrier;
 71     }
 72
 73     @Override
 74     protected String doInBackground(Object[] params) {
 75         Object id = params[0];
 76         String idString = id.toString();
 77         //synchronized (myTPLock) {
 78         Log.d("******", idString + " id: " + Thread.currentThread().getId() + "  " +
 79                 "thread name: " + Thread.currentThread().getName()+" "+MyActivity.j);
 80         //}
 81         MyActivity.j++;
 82         return null;
 83     }
 84 }
 85
 86
 87     @Override
 88     public boolean onCreateOptionsMenu(Menu menu) {
 89         // Inflate the menu; this adds items to the action bar if it is present.
 90         getMenuInflater().inflate(R.menu.my, menu);
 91         return true;
 92     }
 93
 94     @Override
 95     public boolean onOptionsItemSelected(MenuItem item) {
 96         // Handle action bar item clicks here. The action bar will
 97         // automatically handle clicks on the Home/Up button, so long
 98         // as you specify a parent activity in AndroidManifest.xml.
 99         int id = item.getItemId();
100         if (id == R.id.action_settings) {
101             return true;
102         }
103         return super.onOptionsItemSelected(item);
104     }
105 }

运行结果

在这里我们可以验证,我们采用第二种构造方法,在线程工厂中改变 各线程的名字。

在我的代码45行中,我通过for 循环有顺序地传入 a~e 字符串,但是这里的线程并没有按照顺序运行。即是并发了,因为AsyncTask本身是异步线程,我们再看上述代码19行,我设置了个静态的 int 标记,在 AsyncTask() 里面 78~81行没打一次 log 就++,按照我们对异步、并发线程的理解,和可能就会出现,输出的0~5是不按照顺序的,但是上面是按照顺序的,不仅仅是一次的截图,我自己测试过很多次,0~5的输出都是按顺序的。

我自己的总结,可能不一定对,有错请大家指出:

把AsyncTask()异步线程加入到线程池中运行,能够很高效地提高执行任务的速度,如果不加其他操作限制,每个线程的执行可能是不按照顺序的,但是,他们却没有出现抢占资源的状况??

时间: 2024-11-07 23:12:02

java 线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用。的相关文章

Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理

相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理 以下是本文的目录大纲: 一.shutdown()  --  温柔的终止线程池 interruptIdleWorkers()  --  中断空闲worker tryTerminate()  --  尝试终止线程池 二.shutdown

JAVA线程池ThreadPoolExecutor与阻塞队列BlockingQueue .

从Java5开始,Java提供了自己的线程池.每次只执行指定数量的线程,java.util.concurrent.ThreadPoolExecutor 就是这样的线程池.以下是我的学习过程. 首先是构造函数签名如下: [java] view plain copy print ? public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<

java 线程池 ---- ThreadPoolExecutor 类

执行流程 1, 创建线程池后, 默认不会创建线程, 等到有任务带来才创建线程, 即一个线程处理一个任务 2, 当线程数量达到核心线程数时, 任务放进队列, 如果放入队列失败, 创建新线程处理任务(此时线程池线程数大于核心线程数) 3, 如果线程数大于最大线程数, 执行拒绝策略处理任务 构造方法 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, Block

Java: 线程池(ThreadPoolExecutor)中的参数说明

最近在看<阿里巴巴Android开发手册>,里面有这样几句话: [强制]新建线程时,必须通过线程池提供(AsyncTask 或者ThreadPoolExecutor或者其他形式自定义的线程池),不允许在应用中自行显式创建线程. [强制]线程池不允许使用Executors 去创建,而是通过ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险. 个人对线程池的使用也有一段日子了,而且很多时候为了省事用的都是Executors的方式去创建

Java线程池--ThreadPoolExecutor

一.线程池的处理流程 向线程池提交一个任务后,它的主要处理流程如下图所示: 一个线程从被提交(submit)到执行共经历以下流程: 线程池判断核心线程池里的线程是否都在执行任务,如果不是,则创建一个新的工作线程来执行任务.如果核心线程池里的线程都在执行任务,则进入下一个流程; 线程池判断工作队列是否已满.如果工作队列没有满,则将新提交的任务储存在这个工作队列里.如果工作队列满了,则进入下一个流程; 线程池判断其内部线程是否都处于工作状态.如果没有,则创建一个新的工作线程来执行任务.如果已满了,则

Java线程池ThreadPoolExecutor

线程池的好处 1. 降低资源的消耗 通过重复利用已创建的线程降低线程创建和销毁所造成的消耗 2. 提高响应速度 当任务到达时,任务可以不需要等到线程创建就能立即执行 3. 提高线程的可管理型 线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配.调优和监控. 实现原理 当提交一个新任务到线程池时,线程池的处理流程为: 1). 线程池判断核心线程池里的线程是否都在执行任务. 如果不是,则创建一个新的工作线程来执行任务.如果核心线程池里的线程都在执行

java线程池ThreadPoolExecutor理解

Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待.newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行.newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有

深入理解java线程池—ThreadPoolExecutor

几句闲扯:首先,我想说java的线程池真的是很绕,以前一直都感觉新建几个线程一直不退出到底是怎么实现的,也就有了后来学习ThreadPoolExecutor源码.学习源码的过程中,最恶心的其实就是几种状态的转换了,这也是ThreadPoolExecutor的核心.花了将近小一周才大致的弄明白ThreadPoolExecutor的机制,遂记录下来. 线程池有多重要##### 线程是一个程序员一定会涉及到的一个概念,但是线程的创建和切换都是代价比较大的.所以,我们有没有一个好的方案能做到线程的复用呢

java线程池ThreadPoolExecutor类使用详解

在<阿里巴巴java开发手册>中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量:另一方面线程的细节管理交给线程池处理,优化了资源的开销.而线程池不允许使用Executors去创建,而要通过ThreadPoolExecutor方式,这一方面是由于jdk中Executor框架虽然提供了如newFixedThreadPool().newSingleThreadExecutor().newCachedThreadPool(