线程池的原理
线程池使用来管理线程的,之所以称为池,是因为其可以管理多条线程,所以需要用一个集合来管理线程,然后线程池是有大小的,当一个线程池管理的线程数目为计算机的cup数*2+1个的时候,效率为最高。当使用线程池来执行异步任务的时候,线程池会先将这个任务添加到集合中,然后为其创建一个线程,线程方法中有一个while true一直在循环,当集合的size大于0的时候,也就是集合中有异步任务的时候,会调用集合的remove方法,这个方法一方面把这个异步任务从集合中移除掉,另一方面又拿到了这个任务。如果这个任务不为空,就可以执行了。
下面是一些原理代码
public class ThreadPool {
// 定义一个集合来管理线程
LinkedList<Runnable> runnables = new LinkedList<>();
int threadCount = 3;// 定义线程池的容量最大为3
// int count = 0;//定义当前的线程个数
// 使用原子性的操作定义当前线程的个数,避免线程安全问题
AtomicInteger count = new AtomicInteger(3);
// 只能创建三个线程
public void execute(Runnable runnable) {
// 每次执行的时候都把线程添加到集合中
// count++; 这个操作会造成线程的安全问题
runnables.add(runnable);
// 这个方法表示得到当前数值加1的值
if (count.incrementAndGet() < 3) {
createThread();
}
}
// 定义一个创建线程的方法
public void createThread() {
new Thread() {
public void run() {
while (true) {
// 先判断集合中是否有线程
if (runnables.size() > 0) {
// 即从集合中移除了一个线程,又取出了一个异步任务
Runnable remove = runnables.remove();
if (remove != null) {
remove.run();// 如果不为空就run
}
}else {
// 否则就等待 wake();
}
}
};
}.start();
}
}
线程池管理类
使用单例模式创建线程管理器对象
可以根据具体需求
管理多个线程池
线程池管理的线程的个数由需求决定
- 关键的类和方法
- ThreadPoolExecutor 线程池对象
- **pool.execute(runnable);**调用线程池,执行异步任务
- pool.remove(runnable); 移除一个异步任务
/**
* 使用单例模式创建一个线程管理者 管理线程池 管理了两个线程池
*
* @author Sunxin
*
*/
public class ThreadManager {
// 私有化构造方法
private ThreadManager() {
}
// 创建一个私有的静态的对象
private static ThreadManager instance = new ThreadManager();
private ThreadPoolProxy longPool;
private ThreadPoolProxy shortPool;
// 提供一个公有的得到该对象的方法
public static ThreadManager getInstance() {
return instance;
}
// 根据需求开启不同的线程池
// 对外提供一个创建线程池的方法
// 用来处理本地文件.保证线程同步
public synchronized ThreadPoolProxy createShortPool() {
shortPool = new ThreadPoolProxy(3, 3, 5000L);
return shortPool;
}
// 处理联网等耗时的操作的线程池
public synchronized ThreadPoolProxy createLongPool() {
longPool = new ThreadPoolProxy(3, 3, 5000L);
return longPool;
}
// 线程池的代理对象
// 写一个线程池代理的内部类
public class ThreadPoolProxy {
// 线程池对象
private ThreadPoolExecutor pool;
// 线程池能装的线程的个数
private int corePoolSize;
// 如果排队满了,额外开启的线程数
private int maximumPoolSize;
// 存活时间
private long time;
// 构造
public ThreadPoolProxy(int corePoolSize, int maximumPoolSize, long time) {
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.time = time;
}
// 执行一个异步任务
public void execute(Runnable runnable) {
if (pool == null) {
// 创建线程池
/**
* corePoolSize:线程池能装的线程的个数
* maximumPoolSize:如果排队也满了,额外开启的线程数
* keepAliveTime:如果线程没有要执行的任务了,该线程能存活多久
* unit: 存活的时间单位
* workQueue:如果线程池里面管理的线程都已经用了,那么剩下的任务就存到该对象中排队等候
*
*/
pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, time, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(10));
}
// 调用线程池,执行异步任务
pool.execute(runnable);
}
// 移除一个异步任务
public void cancle(Runnable runnable) {
// 判断,当该任务既不能为空,也不能崩溃,更不能停止
if (pool != null && !pool.isShutdown() && !pool.isTerminated()) {
// 移除
pool.remove(runnable);
}
}
}
}
最后就可以通过线程池管理类来创建线程池管理异步的任务了,不用再去new Thread了,相当于一个线程的优化
ThreadManager.getInstance().createLongPool().execute(new Runnable() {
@Override
public void run() {
//操作一些异步任务
}
}
});
}
});
这都是一些个人的理解,难免有偏差。欢迎指正