并发性程序的进阶
一个web应用设计进阶
1 设计一个web应用程序,使用socket连接,执行一个具体的请求后,返回结果给连接的用户,再接入另一个socket,继续执行,这是一个串行化的结构,在并发的情况下是不可想象的,每次只能服务一个用户连接,cpu等资源利用率太低了。
{
connection = socket.accept();
handle(connection);
}
进阶
2 每次过来一个连接,启动一个线程为其执行具体的业务代码增强了并发性,cpu利用率加强,但是这里线程是无限增加,如果并发太高,硬件性能负载不了(线程的创建是耗性能的,内存资源会被耗尽),会出现问题。
{
connection = socket.accept();
new Thread(){
handle(connection);
}.start()
}
3 利用线程池,可以制定同时执行线程的最高数量,限制线程的无线扩张。
executor=Executors.newFixedThreadPool(number);
{
connection = socket.accept();
task = new Thread(){
handle(connection);
}
executor.executor(task); //任务的提交和执行是解耦的
}
在线程池中执行任务要比给任务分配线程要好的多,每次new一个线程是需要耗费资源的,在线程池中,可以利用已有的线程,也可以在请求来的时候,线程已经创建好了,提高了响应。
继续进阶
4 支持线程池的生命周期,关闭线程池shutdown和nowshutdown();
设计一个页面渲染的应用
1 获取完文字和图片后,生成页面的内容
文字的获取用时很少,大部分时间在等待图片的加载,用户大部分的时间在等待图片的加载。这里仅仅是串行化的
2 callable和future来设计
下载图片的时候,让每一个线程去执行,提高性能,下载完成之后,渲染页面,性能有所提高
进阶
3 使用completionService实现
每一张图片下载都使用一个线程去做,每次做完,就把这张图片展示出来,而不是等待所有的图片都下载完成再展示,提高了性能和用户体验。
并发的其他经验
设置过期时间,如果很久不能获取到结果那就结束这个线程,给一个默认的结果。
设置一个时间,时间达到后,我们就把获取到的结果展示出来,不管完成还是没有完成,借助executor.invokeAll()的应用。
并发程序的设计要有合理的设计策略,设计策略就是资源管理器,要结合需求和硬件的能力设计,完善。我们应该在有限的资源下,更好利用这些资源,更大可能的提供并发量和吞吐量。

浙公网安备 33010602011771号