Android开发经验谈:并发编程(线程与线程池)(推荐)
一、线程
在Android开发中,你不可能都在主线程中开发,毕竟要联网,下载数据,保存数据等操作,当然这就离不开线程。
(当然你可以在Android4.0以前的手机里在主线程请求网络,我最早开发的时候,用的手机比较古老。。。)
在Android中你可以随意创建线程,于是就会造成线程不可控,内存泄漏,创建线程消耗资源,线程太多了消耗资源等问题。
具体线程怎么创建我就不在文章里描述了,毕竟这主要将并发编程。。。。
大家知道线程不可控就好了。。。于是就需要对线程进行控制,防止一系列问题出现,这就用到了如下要讲的东西。
二、线程池
线程池:顾名思义,就是放线程的大池子。
如何创建一个线程池?
先说说几个系统的线程池:
- FixedThreadPool创建定长线程的线程池
- CachedThreadPool需要的时候建立新的线程,超时线程销毁
- SingleThreadPool单个线程的线程池
- ScheduledThreadPool可以定时的线程池,创建周期性的任务
这几个线程池不做多余阐述,因为这些线程池的原理都与我下面要讲的有关。。。。
如何自定义线程池(先来了解几个必须知道的参数):
corePoolSize:
核心线程池大小,线程池中主要工作的线程的多少。
maximumPoolSize:
线程池最大线程数。
keepAliveTime:
空闲线程可保持的时间是多久,如果你启用了allowCoreThreadTimeOut方法,你的线程池里的空闲线程在这个时间段后会自动销毁,如果没启用,则只要不超过corePoolSize,空闲线程也不会销毁。
Unit:
keepAliveTime的时间单位
workQueue:
阻塞队列,当任务达到corePoolSize,就会被放入这个队列
常见几种BlockingQueue实现
- ArrayBlockingQueue: 有界的数组队列
- LinkedBlockingQueue:可支持有界/无界的队列,使用链表实现
- PriorityBlockingQueue:优先队列,可以针对任务排序
- SynchronousQueue:队列长度为1的队列,和Array有点区别就是:clientthread提交到blockqueue会是一个阻塞过程,直到有一个workerthread连接上来polltask。
threadFactory:
线程工厂,主要用来创建线程;
handler:
表示当拒绝处理任务时的策略,也就是参数maximumPoolSize达到后丢弃处理的方法。有以下四种取值:
- ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
- ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
- ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
- ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
用户也可以实现接口RejectedExecutionHandler定制自己的策略。
代码展示:
//线程工厂
publicclassTaskThreadFactoryimplementsThreadFactory{
privatefinalAtomicIntegermThreadNumber=newAtomicInteger(1);
privatefinalStringmNamePrefix;
TaskThreadFactory(Stringname){
mNamePrefix=name+"#";
}
publicThreadnewThread(Runnabler){
Threadt=newThread(r,mNamePrefix+mThreadNumber.getAndIncrement());
//if(t.isDaemon())
//t.setDaemon(false);
//
//if(t.getPriority()!=Thread.NORM_PRIORITY)
//t.setPriority(Thread.NORM_PRIORITY);
returnt;
}
}
//重写runnable
publicclassPRunnableimplementsRunnable{
publicstaticfinalintHIGH=1;//优先级高
publicstaticfinalintNORMAL=2;//优先级中等
publicstaticfinalintLOW=3;//优先级低
@IntDef({HIGH,NORMAL,LOW})
@Retention(RetentionPolicy.SOURCE)
public@interfacePriority{}
publicfinalintpriority;
privatefinalRunnablerunnable;
publicintserial;
publicPRunnable(Runnablerunnable){
this(NORMAL,runnable);
}
publicPRunnable(@Priorityintpriority,Runnablerunnable){
this.priority=priority;
this.runnable=runnable;
}
@Override
publicvoidrun(){
if(runnable!=null){
runnable.run();
}
}
/**
*线程队列方式先进先出
*@paramr1
*@paramr2
*@return
*/
publicstaticfinalintcompareFIFO(PRunnabler1,PRunnabler2){
intresult=r1.priority-r2.priority;
returnresult==0?r1.serial-r2.serial:result;
}
/**
*线程队列方式后进先出
*@paramr1
*@paramr2
*@return
*/
publicstaticfinalintcompareLIFO(PRunnabler1,PRunnabler2){
intresult=r1.priority-r2.priority;
returnresult==0?r2.serial-r1.serial:result;
}
}
//线程池实现
publicclassTaskExecutorimplementsExecutor{
privatefinalstaticintQUEUE_INIT_CAPACITY=20;
privatestaticfinalintCORE=3;
privatestaticfinalintMAX=5;
privatestaticfinalintTIMEOUT=30*1000;
privateAtomicIntegerSERIAL=newAtomicInteger(0);//主要获取添加任务
publicstaticclassConfig{
publicintcore;
publicintmax;
publicinttimeout;
publicbooleanallowCoreTimeOut;
publicbooleanfifo;
publicConfig(intcore,intmax,inttimeout,booleanallowCoreTimeOut,booleanfifo){
this.core=core;
this.max=max;
this.timeout=timeout;
this.allowCoreTimeOut=allowCoreTimeOut;
this.fifo=fifo;
}
}
publicstaticConfigdefaultConfig=newConfig(CORE,MAX,TIMEOUT,true,true);
privatefinalStringname;
privatefinalConfigconfig;
privateExecutorServiceservice;
publicTaskExecutor(Stringname){
this(name,defaultConfig);
}
publicTaskExecutor(Stringname,Configconfig){
this(name,config,true);
}
publicTaskExecutor(Stringname,Configconfig,booleanstartup){
this.name=name;
this.config=config;
if(startup){
startup();
}
}
publicvoidstartup(){
synchronized(this){
if(service!=null&&!service.isShutdown()){
return;
}
service=createExecutor(config);
}
}
publicvoidshutdown(){
ExecutorServiceexecutor=null;
synchronized(this){
//交换变量
if(service!=null){
executor=service;
service=null;
}
}
if(executor!=null){
//停止线程
if(!executor.isShutdown()){
executor.shutdown();
}
//回收变量
executor=null;
}
}
privatevoidexecuteRunnable(PRunnablerunnable){
synchronized(this){
if(service==null||service.isShutdown()){
return;
}
runnable.serial=SERIAL.getAndIncrement();
service.execute(runnable);
}
}
@Override
publicvoidexecute(Runnablerunnable){
if(runnableinstanceofPRunnable){
executeRunnable((PRunnable)runnable);
}else{
executeRunnable(newPRunnable(runnable));
}
}
publicFuture>submit(Runnablerunnable){
synchronized(this){
if(service==null||service.isShutdown()){
returnnull;
}
if(runnableinstanceofPRunnable){
((PRunnable)runnable).serial=SERIAL.getAndIncrement();
returnservice.submit(runnable);
}else{
PRunnablepRunnable=newPRunnable(runnable);
pRunnable.serial=SERIAL.getAndIncrement();
returnservice.submit(pRunnable);
}
}
}
publicvoidexecute(Runnablerunnable,@PRunnable.Priorityintpriority){
executeRunnable(newPRunnable(priority,runnable));
}
privateExecutorServicecreateExecutor(Configconfig){
ThreadPoolExecutorservice=newThreadPoolExecutor(config.core,config.max,config.timeout,
TimeUnit.MILLISECONDS,newPriorityBlockingQueue(QUEUE_INIT_CAPACITY,config.fifo?mQueueFIFOComparator:mQueueLIFOComparator),
newTaskThreadFactory(name),newThreadPoolExecutor.DiscardPolicy());
allowCoreThreadTimeOut(service,config.allowCoreTimeOut);
returnservice;
}
publicbooleanisBusy(){
synchronized(this){
if(service==null||service.isShutdown()){
returnfalse;
}
if(serviceinstanceofThreadPoolExecutor){
ThreadPoolExecutortService=(ThreadPoolExecutor)service;
returntService.getActiveCount()>=tService.getCorePoolSize();
}
returnfalse;
}
}
privatestaticfinalvoidallowCoreThreadTimeOut(ThreadPoolExecutorservice,booleanvalue){
if(Build.VERSION.SDK_INT>=9){
allowCoreThreadTimeOut9(service,value);
}
}
@TargetApi(9)
privatestaticfinalvoidallowCoreThreadTimeOut9(ThreadPoolExecutorservice,booleanvalue){
service.allowCoreThreadTimeOut(value);
}
ComparatormQueueFIFOComparator=newComparator(){
@Override
publicintcompare(Runnablelhs,Runnablerhs){
PRunnabler1=(PRunnable)lhs;
PRunnabler2=(PRunnable)rhs;
returnPRunnable.compareFIFO(r1,r2);
}
};
ComparatormQueueLIFOComparator=newComparator(){
@Override
publicintcompare(Runnablelhs,Runnablerhs){
PRunnabler1=(PRunnable)lhs;
PRunnabler2=(PRunnable)rhs;
returnPRunnable.compareLIFO(r1,r2);
}
};
}
以上所述是小编给大家介绍的Android开发经验谈:并发编程(线程与线程池)详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!