您的位置:首页 > 移动开发 > Android开发

Android ThreadPoolExecutor 学会管理你的线程池

2017-12-05 16:56 316 查看
初入Android 时对于线程管理是一无所知。觉得只要可以实现需求就算是完成项目了。但在接触久了之后才发现自己需要学的、做的还有那么那么多。

new Thread(new Runnable() {
@Override
public void run() {
//todo
}
}).start();


原以为开子线程进行耗时操作这样就可以了。但事实却是内存泄漏。。。直接使用 new 声明的子线程也可称呼为野线程,又是在原以为其执行完 run()方法会被 gc 回收。其实呢:线程的创建和销毁都需要时间,当有大量的线程创建和销毁时,那么这些时间的消耗则比较明显,将导致性能上的缺失。大量的线程的创建和销毁很容易导致 gc 频繁的执行,从而发生内存抖动现象,而发生了内存抖动,对于移动端来说,最大的影响就是造成界卡帧。

在多方面的原因下,使用线程池对项目中的线程进行管理会让你的项目性能更加优化。下面是一个简单的线程池使用:

1、创建枚举值来确定线程的优先级

/**
* 优先级枚举值
* @author 49829
* @date 2017/12/5
*/

public enum Priority {
HIGH,NORMAL,LOW
}
2、创建一个 Runnable 来执行需要完成的任务
/**
* 优先级 任务
* @author 49829
* @date 2017/12/5
*/

public class PrioriRunnable implements Runnable {
public final Priority priority;
private final Runnable runnable;
long SEQ;

/**
* 构造函数
* @param priority 优先级
* @param runnable 任务对象
*/
public PrioriRunnable(Priority priority, Runnable runnable) {
this.priority = priority == null ? Priority.NORMAL : priority;
this.runnable = runnable;
}

@Override
public void run() {
this.runnable.run();
}
}3、最后需要创建一个类来实现 ThreadPoolExecutor 来对线程进行管理
import android.support.annotation.NonNull;

import java.util.Comparator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
* 线程管理类
* @author 49829
* @date 2017/12/5
*/

public class MySelfExecutor extends ThreadPoolExecutor{
/**
* 核心线程池大小(默认大小为5)
*/
private static final int CORE_POOL_SIZE = 5;
/**
* 最大线程池队列大小
*/
private static final int MAXIMUM_POOL_SIZE = 128;
/**
* 保持存活时间,当线程数大于corePoolSize的空闲线程能保持的最大时间。
*/
private static final int KEEP_ALIVE = 1;
/**
* 主要获取添加任务
*/
private static final AtomicLong SEQ_SEED = new AtomicLong(0);

private static final ThreadFactory factory=new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
@Override
public Thread newThread(@NonNull Runnable runnable) {
return new Thread(runnable, "线程"+String.valueOf(mCount.getAndDecrement()));
}
};

/**
* 线程队列方式 先进先出
*/
private static final Comparator<Runnable> FIFO = new Comparator<Runnable>() {
@Override
public int compare(Runnable lhs, Runnable rhs) {
if (lhs instanceof PrioriRunnable && rhs instanceof PrioriRunnable) {
PrioriRunnable lpr = ((PrioriRunnable) lhs);
PrioriRunnable rpr = ((PrioriRunnable) rhs);
int result = lpr.priority.ordinal() - rpr.priority.ordinal();
return result == 0 ? (int) (lpr.SEQ - rpr.SEQ) : result;
} else {
return 0;
}
}
};

/**
* 线程队列方式 后进先出
*/
private static final Comparator<Runnable> LIFO = new Comparator<Runnable>() {
@Override
public int compare(Runnable lhs, Runnable rhs) {
if (lhs instanceof PrioriRunnable && rhs instanceof PrioriRunnable) {
PrioriRunnable lpr = ((PrioriRunnable) lhs);
PrioriRunnable rpr = ((PrioriRunnable) rhs);
int result = lpr.priority.ordinal() - rpr.priority.ordinal();
return result == 0 ? (int) (rpr.SEQ - lpr.SEQ) : result;
} else {
return 0;
}
}
};
/**
* 默认工作线程数5
*
* @param fifo 优先级相同时, 等待队列的是否优先执行先加入的任务.
*/
public MySelfExecutor(boolean fifo) {
this(CORE_POOL_SIZE, fifo);
}

/**
* @param poolSize 工作线程数
* @param fifo     优先级相同时, 等待队列的是否优先执行先加入的任务.
*/
public MySelfExecutor(int poolSize, boolean fifo) {
this(poolSize, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, new PriorityBlockingQueue<Runnable>(MAXIMUM_POOL_SIZE, fifo ? FIFO : LIFO), factory);
}

public MySelfExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
}

/**
* 判断当前线程池是否繁忙
* @return
*/
public boolean isBusy() {
return getActiveCount() >= getCorePoolSize();
}

/**
* 提交任务
* @param runnable
*/
@Override
public void execute(Runnable runnable) {
if (runnable instanceof PrioriRunnable) {
((PrioriRunnable) runnable).SEQ = SEQ_SEED.getAndIncrement();
}
super.execute(runnable);
}

}


使用时只需要实例化 一个 MySelfExecutor 调用其 execute(Runnable runnable) 方法就可以实现一个简单的线程池管理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息