并发性程序的进阶

一个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()的应用。

并发程序的设计要有合理的设计策略,设计策略就是资源管理器,要结合需求和硬件的能力设计,完善。我们应该在有限的资源下,更好利用这些资源,更大可能的提供并发量和吞吐量。

 

posted @ 2017-10-07 22:42  Hill_Dong  阅读(106)  评论(0)    收藏  举报