java线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用
简单说下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()) 并发运行,例如下面的代码片段
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
; i < 10; i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Log.d("******", Thread.currentThread().getId() + " thread name: " + Thread.currentThread().getName()+"--"+index);
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
运行结果如下

因为线程池大小为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() 是怎样联系的 :
package cn.mr.ams.threadpool;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public class MyActivity extends Activity {
CyclicBarrier barrier = );
;
public final Object myTPLock = new Object();//对象锁,主要用来实现同步,我这里并没有使用
public static ExecutorService myTP = null;//和 AsyncTask() 连用
);//第一种构造函数
//private List<String> test = new ArrayList<String>();
private String[] test = new String[]{"a--","b--","c--","d--","e--"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
//采用 第二种 构造方法,改写下 线程工厂 对象,使每次加入线程池中的线程都能被设置定义的属性
myTP = Executors.newFixedThreadPool(3, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
//我把所加入到改线程池的线程全改名了
t.setName("LinGuanHong");
// 设置线程的优先级别
t.setPriority(Thread.NORM_PRIORITY - 1);
return t;
}
});
for(String item : test) {
//通过 for 循环,把 AsyncTask() 异步线程逐个 加入到线程池中
new myThread(barrier).executeOnExecutor(myTP,item);
//SystemClock.sleep(10);//能起到一定的延时,实现按顺序进行
}
/*for (int i = 0; i < 10; i++) {
final int index = i;
myTP_1.execute(new Runnable() {
@Override
public void run() {
try {
Log.d("******", Thread.currentThread().getId() + " thread name: " + Thread.currentThread().getName()+"--"+index);
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}*/
}
public class myThread extends AsyncTask<Object, Void, String> {
private CyclicBarrier barrier = null;
public myThread(CyclicBarrier barrier){
this.barrier = barrier;
}
@Override
protected String doInBackground(Object[] params) {
Object id = params[0];
String idString = id.toString();
//synchronized (myTPLock) {
Log.d("******", idString + " id: " + Thread.currentThread().getId() + " " +
"thread name: " + Thread.currentThread().getName()+" "+MyActivity.j);
//}
MyActivity.j++;
return null;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
运行结果

在这里我们可以验证,我们采用第二种构造方法,在线程工厂中改变 各线程的名字。
在我的代码45行中,我通过for 循环有顺序地传入 a~e 字符串,但是这里的线程并没有按照顺序运行。即是并发了,因为AsyncTask本身是异步线程,我们再看上述代码19行,我设置了个静态的 int 标记,在 AsyncTask() 里面 78~81行没打一次 log 就++,按照我们对异步、并发线程的理解,和可能就会出现,输出的0~5是不按照顺序的,但是上面是按照顺序的,不仅仅是一次的截图,我自己测试过很多次,0~5的输出都是按顺序的。
我自己的总结,可能不一定对,有错请大家指出:
把AsyncTask()异步线程加入到线程池中运行,能够很高效地提高执行任务的速度,如果不加其他操作限制,每个线程的执行可能是不按照顺序的,但是,他们却没有出现抢占资源的状况??
java线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用的更多相关文章
- java 线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用。
转载请声明出处谢谢!http://www.cnblogs.com/linguanh/ 这里主要使用Executors中的4种静态创建线程池实例方法中的 newFixedThreadPool()来举例讲 ...
- Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理
相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...
- Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理
相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...
- Java线程池ThreadPoolExecutor使用和分析(一)
相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...
- Java线程池ThreadPoolExecutor类源码分析
前面我们在java线程池ThreadPoolExecutor类使用详解中对ThreadPoolExector线程池类的使用进行了详细阐述,这篇文章我们对其具体的源码进行一下分析和总结: 首先我们看下T ...
- java线程池ThreadPoolExecutor使用简介
一.简介线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:ThreadPoolExecutor(int corePoolSize, int m ...
- Java 线程池(ThreadPoolExecutor)原理分析与使用
在我们的开发中"池"的概念并不罕见,有数据库连接池.线程池.对象池.常量池等等.下面我们主要针对线程池来一步一步揭开线程池的面纱. 使用线程池的好处 1.降低资源消耗 可以重复利用 ...
- Java 线程池(ThreadPoolExecutor)原理解析
在我们的开发中“池”的概念并不罕见,有数据库连接池.线程池.对象池.常量池等等.下面我们主要针对线程池来一步一步揭开线程池的面纱. 有关java线程技术文章还可以推荐阅读:<关于java多线程w ...
- Java线程池(ThreadPoolExecutor)原理分析与使用
在我们的开发中"池"的概念并不罕见,有数据库连接池.线程池.对象池.常量池等等.下面我们主要针对线程池来一步一步揭开线程池的面纱. 使用线程池的好处 1.降低资源消耗 可以重复利用 ...
随机推荐
- win8以上系统查看iis网站进程内存占用情况
由于win8以上系统在任务管理器中已经屏蔽了具体的IIS网站的进程,在进程以及详细中无法区分是哪个站点了,所以我们需要先知道各站点对应的进程pid,然后再到任务管理器中根据具体的pid查看资源占用情况 ...
- nodeppt的使用教程
为什么选择nodeppt 这可能是迄今为止最好的网页版演示库 基于GFM的markdown语法编写 支持html混排,再复杂的demo也可以做! 支持多个皮肤:colors-moon-blue-dar ...
- Go 语言环境安装
Go 语言支持以下系统: Linux FreeBSD Mac OS X(也称为 Darwin) Window 安装包下载地址为:https://golang.org/dl/. 各个系统对应的包名: 操 ...
- matplotlib画散点图,并在散点处打上相应标签
运行环境: py3.6 matplotlib 2.1.2 x = [2,4,6,7,8,5,4,3] y = [3,6,5,8,4,3,2,4] txt = ['我','今','晚','上','吃', ...
- LAB颜色空间各通道的取值范围
简介 LAB颜色空间在计算机视觉中经常被使用,知道L,A,B三个通道的取值范围有一定的意义. OpenCV获取LAB取值范围 下面是一段实验代码,用于获取LAB的取值范围. 基本思路是,排列组合所有R ...
- J2EE进阶(十五)MyEclipse反向工程实现从数据库反向生成实体类之Hibernate方式
J2EE进阶(十五)MyEclipse反向工程实现从数据库反向生成实体类之Hibernate方式 反向工程又称逆向工程. 开发项目涉及到的表太多,一个一个的写JAVA实体类很是费事.MyEcl ...
- springMVC源码分析--异常处理机制HandlerExceptionResolver简单示例(一)
springMVC对Controller执行过程中出现的异常提供了统一的处理机制,其实这种处理机制也简单,只要抛出的异常在DispatcherServlet中都会进行捕获,这样就可以统一的对异常进行处 ...
- 【Netty源码学习】DefaultChannelPipeline(三)
上一篇博客中[Netty源码学习]ChannelPipeline(二)我们介绍了接口ChannelPipeline的提供的方法,接下来我们分析一下其实现类DefaultChannelPipeline具 ...
- SQL 数据库语言分析总结(一)
SQL语言是被广泛采用的数据库的学习语言,之前在本科的时候已经学习过了,但是后来又忘记了,所以这次简单的总结一下. 分类 交互式sql语言,交互式语言主要是利用一些数据库工具,比如mysql的终端工具 ...
- 【java虚拟机序列】java中的垃圾回收与内存分配策略
在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...