Android线程池的入门
来源:互联网 发布:网络红人毒药身世 知乎 编辑:程序博客网 时间:2024/06/05 04:54
此博客是我通过观看麦子学院的视频进行总结的,视频地址:
http://www.maiziedu.com/course/918-13459/
JAVA线程池分为以下几种
- newCachedThreadPool
- newFixedThreadPool
- newSingleThreadExecutor
- newScheduledThreadPool
- 总结
首先我们先来想一下我们平常都是怎样创建的:
匿名类的创建
new Thread(new Runnable() { @Override public void run() { } }).start();
这样来看普通创建是存在弊端的(下面会结合代码说明)
- 每次new Thread 新创建对象的性能差
- 线程缺乏统一管理,可能无限制的新建线程,相互之间竞争,可能会占用过多的系统资源导致OOM
- 缺乏更多的功能,比如定时执行,定期执行,线程中断
线程池的好处
1. 重用存在的线程,减少对象的创建,消亡的开销,性能佳
2. 可有效控制最大并发的线程数,提高系统资源使用率,避免过多竞争,避免堵塞
3. 提供定时执行,定期执行,单线程,并发数控制等功能
下面就是怎么使用线程池
所有的案例我们都是使用for循环创建了10个任务,有的任务是耗时的有的是不耗时的
new Thread
这个就不用过多的解释了。。。。。。
代码:
for(int i=0;i<10;i++){ final int index=i; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(new Runnable() { @Override public void run() { Log.e("TAG","new Thread:"+"\n"+"name:"+Thread.currentThread(). getName()+"\n"+"i:"+index); } }).start(); }
打印日志:
可以看出每一个Thread的name 都是不一样的,这样可不就创建了很多个对象了吗,造成资源浪费
newCachThreadPoll
简介:创建一个可缓存的线程池,如果线程池长度超过处理需要,可灵活回收空线程,若无可回收,继续创建新的线程
代码:
//所有的都是ExecutorService的一个对象 ExecutorService cacheThreadPoll= Executors.newCachedThreadPool(); //创建10个子线程的任务 for (int i=0;i<10;i++){ //i在下面取不到,赋值给index final int index=i; //每执行一次任务就休息两秒钟 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } cacheThreadPoll.execute(new Runnable() { @Override public void run() { Log.e("TAG","cacheThreadPoll"+"\n"+"name:"+Thread.currentThread(). getName()+"\n"+"i:"+index); } }); }
打印日志:
这些线程的名字都是一样的,也就是说只创建了一个对象,就避免了资源的浪费
那么当第一个任务还没执行完,没有空闲的线程对象可以使用了会怎么办呢,我们就可以模拟一下(把休眠去掉即可)
可以看出来这个线程池中创建了5个线程对象,有的线程对象被使用了多次,并且i的打印顺序不对,那为什么我们停止休眠操作后会出现这个问题呢
i的执行顺序:
CPU在处理子线程任务的时候是随机的,也是穿插执行的,我们同时并发了10个子线程0123…9,因为没有睡眠,所以这些子线程几乎是同时执行,它在执行的时候会随机执行,并且可能会在1上执行一点然后又去2执行,2还没执行完又回到1执行了,所以就造成了i的打印不是顺序的
线程池开启了5个子线程:
当前1号线程被占用,所以只能再开启2号线程去执行其他任务了,当1号线程执行完它的任务之后,它会看看哪些任务还是没有执行的,再去执行其他的任务,最后2号执行完任务并发现没有别的任务了,2号就被回收了
newFixedThreadPool
简介:创建一个定长线程池,可控制线程最大的并发数,超出线程会在队列中等待
代码:
//定义线程池的大小为3 ExecutorService fixedThreadPool=Executors.newFixedThreadPool(3); for (int i=0;i<10;i++){ final int index=i; fixedThreadPool.execute(new Runnable() { @Override public void run() { Log.e("TAG","fixedThreadPool:"+"\n"+"name:"+Thread.currentThread(). getName()+"\n"+"i:"+index); } }); }
打印日志:
和上面不同,这里不管有几个任务并发,只会有3个线程对象去执行任务,其他的任务只能等着了~
newSingleThreadExecutor
简介:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO,LIFO)优先执行
代码:
//创建一个单一线程池 ExecutorService singleThreadPool = Executors.newSingleThreadExecutor(); for (int i = 0; i < 10; i++) { final int index = i; singleThreadPool.execute(new Runnable() { @Override public void run() { Log.e("TAG", "singleThreadPool:" + "\n" + "name:" + Thread.currentThread(). getName() + "\n" + "i:" + index); } }); }
打印日志:
不管我们的任务有多少,我们的线程对象只会开启一个
newScheduledThreadPool
简介:创建一个定长的线程池,支持定时及周期性任务的执行,比如两秒之后想做什么,或者是每两秒想做什么
定时执行:
//得到当前毫秒数 Log.e("TAG", "textScheduled start:"+System.currentTimeMillis()); //创建一个定长的线程池,并且里面的线程对象都是单一的 ScheduledExecutorService scheduledExecutorService = Executors. newSingleThreadScheduledExecutor(); //定义3秒之后执行什么 scheduledExecutorService.schedule(new Runnable() { @Override public void run() { //三秒钟之后会执行到打印Log这一步 Log.e("TAG", "delay 3 seconds:"+System.currentTimeMillis()); }
打印日志:
中间是相差三秒钟的,并且这个线程只执行了一次
周期性的执行:
//周期性执行任务,2秒后执行,每隔3秒执行一次 scheduledExecutorService.scheduleAtFixedRate(new Runnable() { //控制执行次数的变量 @Override public void run() { Log.e("TAG", "delay 2 seconds,and execute every 3seconds"); } }, 2, 3, TimeUnit.SECONDS);
打印日志:
从textScheduled start 到下面的delay…..的带引中间相差了2s,然后每个delay……之间的打印中间相差了3s而且是一直打印下去
停止周期循环:
scheduledExecutorService.shutdown();
总结
不难看出他们之间的使用是有一些规律的
- 创建对象——— Executors.newXXXXExecutor( ) ;创建出一个 ExecutorService 的对象,当然 ScheduledExecutorService 是 newScheduledThreadPool 的对象
- 将任务放置到线程池———xxxx.execute,参数传递的是一个Runnable接口(newScheduledThreadPool 例外 )
- Android线程池的入门
- [Android]Thread线程入门1
- [Android]Thread线程入门2
- Android的线程与线程池
- Android的线程和线程池
- Android的线程和线程池
- Android的线程和线程池
- Android的线程和线程池
- 十一、Android的线程和线程池
- Android的线程和线程池
- Android 的线程跟线程池
- Android的线程和线程池(一)
- Android的线程和线程池
- Android的线程和线程池
- Android的线程和线程池
- Android的线程与线程池
- Android的线程和线程池
- Android的线程和线程池
- 3种方法解决交换两个数
- A
- win7下cuda8.0安装跑gpu版tensorflow
- LED灯
- HDU
- Android线程池的入门
- js将object转为json数据格式(java)
- 17暑假多校联赛1.3 HDU 6035 Colorful Tree
- Spring MVC文件上传下载(亲测可用)
- POJ
- 常用Java虚拟机调试和配置参数
- 泛型List<T>中方法Remove不能删除对象的解决
- 社会心理学随机抽样解释
- 人工智能浪潮