------------ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------
线程池
线程池的作用:
线程池作用就是限制系统中执行线程的数量。
根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳
效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线
程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的
任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一
个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;
否则进入等待队列。
为什么要用线程池:
1:减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执
行多个任务
2:可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为因
为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开
的越多,消耗的内存也就越大,最后死机)
线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存
放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线
程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复
创建线程对象所带来的性能开销,节省了系统的资源。
要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚
的情况下,很有可能配置的线程池不是较优的,因此在Executors类里
面提供了一些静态工厂,生成一些常用的线程池。
标记一下比较重要的类:
ExecutorService:真正的线程池接口。
ScheduledExecutorService:能和Timer/TimerTask类似,解决那些需要任务重
复执行的问题。
ThreadPoolExecutor:ExecutorService的默认实现。
ScheduledThreadPoolExecutor:
继承ThreadPoolExecutor的ScheduledExecutorService接口实现,
周期性任务调度的类实现。
要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,
很有可能配置的线程池不是较优的,因此在Executors类里面提供了一些静态工厂,
生成一些常用的线程池。
newSingleThreadExecutor:创建一个单线程的线程池。这个线程池只有一个线程在
工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因
为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务
的执行顺序按照任务的提交顺序执行。
newFixedThreadPool:创建固定大小的线程池。每次提交一个任务就创建一个线程,
直到线程达到 线程池的最大大小。线程池的大小一旦达到最大值就会保
持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新
线程。
newCachedThreadPool:创建一个可缓存的线程池。如果线程池的大小超过了处理
任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任
务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会
对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够
创建的最大线程大小。
newScheduledThreadPool:创建一个大小无限的线程池。此线程池支持定时以及周
期性执行任务的需求。
newSingleThreadExecutor:创建一个单线程的线程池。此线程池支持定时以及周期
性执行任务的需求。
例:单任务线程池:
//创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
ExecutorService pool = Executors.newSingleThreadExecutor();
例如张老师的7k面试题中用到的线程池
//模拟车辆不断随机上路的过程
ExecutorService pool = Executors.newSingleThreadExecutor();
//新建单独的线程,返回线程池,给线程池提交一个任务,线程池就会挑选一个空闲的
//线程来完成这个任务
/*Executors工具往往以S结尾的,里面多是静态方法。这个叫执行器
static ExecutorService |newSingleThreadExecutor()
创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
newFixedThreadPool(int nThreads)参数为池中的线程数
创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。
意思是一上来就产生很多线程,这些线程封装为一个组里面,以后有任务的时候,
线程池里哪个线程空闲就交予哪个线程来做
*/
/*execute | void execute(Runnable command)
在未来某个时间执行给定的命令。该命令可能在新的线程、已入池的线程或者
正调用的线程中执行,这由 Executor 实现决定。
参数:command - 可运行的任务
意思是挑选某个线程来执行*/
pool.execute(new Runnable()
{
public void run()
{
for(int i=1;i<1000;i++)
{
try
{
Thread.sleep((new Random().nextInt(10) + 1) * 1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
vechicles.add(Road.this.name + "_" + i);
}
}
});
// 周期性任务调度的类实现
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run()
{
if(vechicles.size()>0)
{
boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
if(lighted)
{
System.out.println(vechicles.remove(0) + " is traversing !");
}
}
}
},
1, //首次执行的延迟时间
1, //再过多长时间继续执行上一次任务。
TimeUnit.SECONDS);//规定执行时间度量单位
/*scheduleAtFixedRate 计划固定频率来做这件事
ScheduledFuture<?> scheduleAtFixedRate(
Runnable command,
long initialDelay,
long period,
TimeUnit unit)枚举类表示单元粒度的时间段
创建并执行一个在给定初始延迟后首次启用的定期操作,
后续操作具有给定的周期;
也就是将在 initialDelay 后开始执行,然后在 initialDelay
+period 后执行,
接着在 initialDelay + 2 * period 后执行,依此类推。如果任务的
任何一个执行遇到异常, 则后续执行都会被取消。否则,只能通过执
行程序的取消或终止方法来终止该任务。
如果此任务的任何一个执行要花费比其周期更长的时间,则将推迟后续执行,
但不会同时执行。
参数:command - 要执行的任务
initialDelay - 首次执行的延迟时间
period - 连续执行之间的周期
unit - initialDelay 和 period 参数的时间单位
schedule 给定延迟后操作一次*/
}
------------ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------