先看两个概念:
线程:进程中负责程序执行的执行单元。一个进程中至少有一个线程。
多线程:解决多任务同时执行的需求,合理使用CPU资源。多线程的运行是根据CPU切换完成,如何切换由CPU决定,因此多线程运行具有不确定性。
线程池基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。
Java里面线程池的顶级接口是 Executor,不过真正的线程池接口是 ExecutorService, ExecutorService 的默认实现是 ThreadPoolExecutor;普通类 Executors 里面调用的就是 ThreadPoolExecutor。
public interface Executor {
void execute(Runnable command);
}
public interface ExecutorService extends Executor {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
...
}
public class Executors {
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
...
}
在Java中Executors是一个关于线程池的父亲接口该类中具有多个构造方法,用来完成不同类型的线程池的创建
1、固定大小的线程池
Executors threadPool= (Executors) Executors.newFixedThreadPool(3);
固定大小的线程池当多个任务同时提交时,始终在线程池中具有一开始设置的线程数目,多余该数目的其他任务暂时阻塞在队列中等待线程池的操作。
2、具有缓冲的线程池(可变大小的线程池)
Executors threadPool= (Executors) Executors.newCachedThreadPool();
此类型线程池大小随着任务数量的多少,进行浮动的线程数创建,线程池中的线程数是浮动的。
3、单个线程的线程池
Executors threadPool=Executors.newSingleThreadExecutor();
此类线程池中的线程数始终只有一个,并且不会增多或者减少。
比较 单个线程的线程池和单独一个线程:
在Android中使用的线程池是ThreadPoolExecutor
ThreadPoolExecutor threadPoolExecutor= new ThreadPoolExecutor(int corePoolSize, int maxinumPoolSize, long keepAliveTime, TimeUnit unit, BlockingDeque<Runnable> workQueue, ThreadFactory threadFactory);
各参数含义:
使用示例:
public class MyThreadFactory {
//Android的线程池类
private static ThreadPoolExecutor threadPoolExecutor=null;
//获取当前用户的手机的CPU的核心数
private static int num=Runtime.getRuntime().availableProcessors();
//用于存储提交任务的任务队列
private static BlockingDeque<Runnable> workQueue=new LinkedBlockingDeque<>(num*50);
private MyThreadFactory(){
}
public static ThreadPoolExecutor getThreadPoolExecutor(){
if(null==threadPoolExecutor){
threadPoolExecutor=new ThreadPoolExecutor(num*2, num*4, 8, TimeUnit.SECONDS, workQueue, new ThreadPoolExecutor.CallerRunsPolicy());
// threadPoolExecutor=new ThreadPoolExecutor(1, 1, 8, TimeUnit.SECONDS, workQueue, new ThreadPoolExecutor.CallerRunsPolicy());
}
return threadPoolExecutor;
}
}