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

android中关于对线程池的理解以及操作

2016-08-11 12:55 295 查看
在android中很多时候我们需要处理一些比较耗时的操作,而在android中明确的规定主线程不能进行一些耗时的操作,如果要进行一些耗时的操作,那么就必须要开启子线程去处理。那么问题就来了。是否我们可以不断地去new出子线程呢?答案是否定的。因为这样子会造成系统的资源消耗过大。因此我们要想解决这个问题就需要引入一个线程池的概念。

所谓的线程池,我们可以通过一个简单的案例来理解。某天你突然发现你的钱包的钱不够用了,那怎么办?去银行取呗!这时我们可以将某某银行比作一个线程池。银行里面肯定有为群众办理业务的窗口,这些窗口我们就可以比作是线程。一个银行不可能有无数个办理业务的窗口,都有一个最大数值。假设某某银行这里面一共有20个办理业务的窗口,也就是说最多它只能有20个窗口去办理业务,不可能超过20.这个我们就可以把它比作线程池中最大的线程数。不过现在银行的行长认为现在业务比较少,开10个窗口就够了,也就是说当前只需要开启10个窗口就足够办理业务了,不需要同时开启20个那么多去浪费资源。这个我们就可以把它比作是线程池中的核心线程数。在银行办理业务的时候工作人员不可能像机器一样无休止的一直工作的吧!他有时候需要停下来休息一会儿,喝喝水或者上上厕所。这个我们就可以比作线程的保持活跃时间,也就是休息时间。很不巧的是今天你去银行办理取钱业务的时候发现人山人海啊!到处都是办理业务的人。这时候银行的行长发话了,把之前没有开启的空闲窗口都开启吧!这样办理业务会快一些,办理业务的群众才不会等那么久。可是今天实在是太多人了,20个窗口同时开启了都无法满足现有的状态啊!整个银行都挤满了人啊!这时候银行的行长也没办法了,怎么办?这时候行长又发话了。这样吧!我们先把银行的门关闭一下,让在里面的正在排队的人先办理业务,接下来要来银行办理业务的人先在银行的门外面等着吧!等到里面的人办理好业务,银行有资源为外面等待的人办理业务的时候再把银行的门开启,让外面的人进来办理业务吧!

整个线程池的工作机制就类似于上面的银行办理业务的例子,希望大家看完后对线程池有一个全新的认识。好了,下面就让我们来写对应的代码练练手吧!

#

详细代码如下:

#

public class ThreadPoolConstructor {
private static ThreadPool mThreadPoolCenter;
//获取线程池的对象
public static ThreadPool getThreadPool() {
if (mThreadPoolCenter == null) {
// 获取CPU个数,获取CPU个数的主要目的是为了根据不同的手机CPU的核数不同,从而设置线程的数目不同
int CPUNum = Runtime.getRuntime().availableProcessors();
//设置线程的最大线程数最好的方案就是根据CPU的核数乘以2再加上1.
int count = CPUNum * 2 + 1;
if (CPUNum < 8) {
count = 8;
}
mThreadPoolCenter = new ThreadPool(count, count, 0L);
}

return mThreadPoolCenter;
}

public static class ThreadPool {
private int coreThreadNumber;// 核心线程的数目
private int maxThreadNumber;// 最大线程的数目
private long keepThreadTime;// 保持线程的活跃时间(即为:休息时间)
private ThreadPoolExecutor executor;
private ThreadPool(int coreThreadNumber, int maxThreadNumber,
long keepThreadTime) {
this.coreThreadNumber = coreThreadNumber;
this.maxThreadNumber = maxThreadNumber;
this.keepThreadTime = keepThreadTime;
}
//执行对应线程任务
public void execute(Runnable r) {
if (executor == null) {
// 参数一:核心线程的数目
// 参数二:最大线程的数目
// 参数三:保持线程的活跃时间(即为:休息时间)
// 参数四:活跃时间的单位
// 参数五:线程队列
// 参数六:线程工厂
// 参数七:异常处理策略
executor = new ThreadPoolExecutor(coreThreadNumber,
maxThreadNumber, keepThreadTime, TimeUnit.SECONDS,
new LinkedBlockingDeque<Runnable>(),
Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
}
executor.execute(r);// 将当前Runnable对象放在线程池中
}

// 移除对应的线程任务
public void cancel(Runnable r) {
if (executor != null) {
executor.getQueue().remove(r);
}
}
}
}

public class MainActivity extends AppCompatActivity {

a56a
private Context mContext;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
useThreadPoolConstructorMethod();
}

//使用线程池的方法
private void useThreadPoolConstructorMethod() {
//只需要调用下面这一句你就可以使用自己构造出来的线程池了
ThreadPoolConstructor.getThreadPool().execute(new Runnable() {
@Override
public void run() {
SystemClock.sleep(3000);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, "成功调用", Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息