Java 并发专题 : Executor具体介绍 打造基于Executor的Webserver
转载标明出处:http://blog.csdn.net/lmj623565791/article/details/26938985
继续并发,貌似并发的文章非常少有人看啊~哈~
今天准备具体介绍java并发包下的Executor,以及Java提供了非常多灵活的且极其方便的线程池的创建。
嗯。那就慢慢说,大家肯定都学过Socket,JavaSe的时候写聊天程序,游戏的server。以及Android程序自己须要提供server的。都会拿Socket来自己写个:
最初我们的server可能写成这样:
1、单线程server
package com.zhy.concurrency.executors; import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; /**
* 单线程Webserver
*
* @author zhy
*
*/
public class SingleThreadWebServer
{ public static void main(String[] args) throws IOException
{ ServerSocket server = new ServerSocket(7711);
while (true)
{
Socket client = server.accept();
handleReq(client);
} } /**
* 处理请求
* @param client
*/
private static void handleReq(Socket client)
{
} }
这种server代码非常easy,理论上也是正确的,可是在实现的环境中却非常糟糕,由于它每次仅仅能处理一个请求。假设每一个请求的耗时过长,后面的请求会长时间等待或者超时错误。
于是乎,出现了以下这种写法:
2、每一个请求分配一个线程的server
package com.zhy.concurrency.executors; import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 为每一个请求分配一个线程
* @author zhy
*
*/
public class TaskPreThreadServer
{
public static void main(String[] args) throws IOException
{
ServerSocket server = new ServerSocket(8811);
while (true)
{
final Socket client = server.accept();
new Thread()
{
public void run()
{
handleReq(client);
};
}.start();
}
} protected static void handleReq(Socket client)
{ }
}
为每一个请求开辟一个线程,首先我得承认我也经经常使用这种写法~可是我们还是要吐槽下这样写法的不足:
a、线程的生命周期的开销还是相当高的,大量的线程的创建将消耗大量的计算机资源
b、可创建线程的数量存在一个限制值(这个值由平台认为,且受非常多因素的制约),假设超过这个限制,可能会报OOM错误
c、在一定范围内。添加线程能够提高系统吞吐量,可是超过了这个范围。就物极必反了,仅仅会减少程序的运行速度。
所以我们要继续改进我们的server代码,Executor提供了非常方便的方式:
3、基于Executor的server
package com.zhy.concurrency.executors; import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors; /**
* 基于Executor的server
* @author zhy
*
*/
public class TaskExecutionServer
{
private static final int THREAD_COUNT = 100;
private static final Executor exec = Executors
.newFixedThreadPool(THREAD_COUNT); public static void main(String[] args) throws IOException
{
ServerSocket server = new ServerSocket(9911);
while (true)
{
final Socket client = server.accept();
Runnable task = new Runnable()
{
@Override
public void run()
{
handleReq(client);
}
};
exec.execute(task);
} } protected static void handleReq(Socket client)
{ }
}
创建一个固定长度的线程池,既攻克了单线程的堵塞问题。也攻克了无限创建线程带来的内存消耗过多等问题。
4、Executors的API介绍
Java类库提供了很多静态方法来创建一个线程池:
a、newFixedThreadPool 创建一个固定长度的线程池。当到达线程最大数量时,线程池的规模将不再变化。
b、newCachedThreadPool 创建一个可缓存的线程池。假设当前线程池的规模超出了处理需求,将回收空的线程。当需求添加时。会添加线程数量;线程池规模无限制。
c、newSingleThreadPoolExecutor 创建一个单线程的Executor,确保任务对了,串行运行
d、newScheduledThreadPool 创建一个固定长度的线程池。并且以延迟或者定时的方式来运行。相似Timer;后面后单独使用Blog介绍它与Timer差别
小结一下:在线程池中运行任务比为每一个任务分配一个线程优势很多其它,通过重用现有的线程而不是创建新线程,能够在处理多个请求时分摊线程创建和销毁产生的巨大的开销。
当请求到达时,通常工作线程已经存在,提高了响应性。通过配置线程池的大小,能够创建足够多的线程使CPU达到忙碌状态,还能够防止线程太多耗尽计算机的资源。
好了,结束~欢迎大家留言~
Java 并发专题 : Executor具体介绍 打造基于Executor的Webserver的更多相关文章
- Java 并发专题 : Executor详细介绍 打造基于Executor的Web服务器
转载标明出处:http://blog.csdn.net/lmj623565791/article/details/26938985 继续并发,貌似并发的文章很少有人看啊~哈~ 今天准备详细介绍java ...
- Java 并发和多线程(一) Java并发性和多线程介绍[转]
作者:Jakob Jenkov 译者:Simon-SZ 校对:方腾飞 http://tutorials.jenkov.com/java-concurrency/index.html 在过去单CPU时 ...
- Java并发性和多线程介绍
java并发性和多线程介绍: 单个程序内运行多个线程,多任务并发运行 多线程优点: 高效运行,多组件并行.读->操作->写: 程序设计的简单性,遇到多问题,多开线程就好: 快速响应,异步式 ...
- Java 并发专题 : CyclicBarrier 打造一个安全的门禁系统
继续并发专题~ 这次介绍CyclicBarrier:看一眼API的注释: /** * A synchronization aid that allows a set of threads to all ...
- Java并发专题
——参考于码农求职小助手公众号 1.并行和并发有什么区别? 1. 并行是指两个或者多个事件在同一时刻发生:而并发是指两个或多个事件在同一时间间隔发生: 2. 并行是在不同实体上的多个事件,并发是在同一 ...
- Java 并发专题 :FutureTask 实现预加载数据 在线看电子书、浏览器浏览网页等
继续并发专题~ FutureTask 有点类似Runnable,都可以通过Thread来启动,不过FutureTask可以返回执行完毕的数据,并且FutureTask的get方法支持阻塞. 由于:Fu ...
- Java 并发专题 : Semaphore 实现 互斥 与 连接池
继续并发方面的知识.今天介绍Semaphore,同样在java.util.concurrent包下. 本来准备通过例子,从自己实现到最后使用并发工具实现,但是貌似效果并不是很好,有点太啰嗦的感觉,所有 ...
- Java 并发专题 :闭锁 CountDownLatch 之一家人一起吃个饭
最近一直整并发这块东西,顺便写点Java并发的例子,给大家做个分享,也强化下自己记忆. 每天起早贪黑的上班,父母每天也要上班,话说今天定了个饭店,一家人一起吃个饭,通知大家下班去饭店集合.假设:3个人 ...
- Java 并发专题 : Timer的缺陷 用ScheduledExecutorService替代
继续并发,上篇博客对于ScheduledThreadPoolExecutor没有进行介绍,说过会和Timer一直单独写一篇Blog. 1.Timer管理延时任务的缺陷 a.以前在项目中也经常使用定时器 ...
随机推荐
- jQuery选择器(基本过滤选择器)第三节
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...
- RPA(Robotic Process Automation)的概要介绍
最近因为公司业务的需要,开始关注RPA的内容,奈何国内相关的信息太少,只能硬着头皮啃英文了. 下面记录的内容作为学习笔记,有不对的地方请大家指教. 首先RPA(Robotic Process Auto ...
- Python做的第一个小项目-模拟登陆
1. 用户输入帐号密码进行登陆 2. 用户信息保存在文件内 3. 用户密码输入错误三次后锁定用户 主要采用循环语句和条件语句进行程序流程的控制,加入文件的读写操作 while True: choice ...
- 谷歌浏览器Chrome播放rtsp视频流解决方案
找半天,HTML5的可以支持RTMP 但是无法播放RTSP,flash也止步于RTMP,最后同事推荐了个开源的好东东 VLC ,请教谷歌大神之后,这货果然可以用来让各浏览器(IE activex方式, ...
- ABP框架个人开发实战(1)_环境搭建
前言 之前关注ABP框架有一阵子了,一直没有潜下心来实际研究一下.最近想自己建站,以后有自己的功能开发项目,可以在自己的站点上开发,并一步步的完善,所以找个比较好用的框架迫在眉睫,选来选去,决定用AB ...
- OpenCV二维Mat数组(二级指针)在CUDA中的使用
CUDA用于并行计算非常方便,但是GPU与CPU之间的交互,比如传递参数等相对麻烦一些.在写CUDA核函数的时候形参往往会有很多个,动辄达到10-20个,如果能够在CPU中提前把数据组织好,比如使用二 ...
- 从事务角度粗窥架构的可扩展性和可维护性:内容整理自java web轻量级开发面试教程
大家多少了解过架构,也听说过使用架构后,代码和可维护性和重用性能大大提升.这里我们来通过一些关于事务的实例,来感性地体会下架构带来的在可维护性方面的便利.本文来是从 java web轻量级开发面试教程 ...
- MySQL GTIDs(global transaction identifiers)
1.如何定义和生成GTIDs 唯一性:在所有主从库都是唯一的,由二元组构成 每个事务和GTIDs之间都有1:1映射 GTID = source_id:transaction_id source_id标 ...
- springmvc跨域+token验证(app后台框架搭建二)
这是app后台框架搭建的第二课,主要针对app应用是跨域的运用,讲解怎么配置跨域服务:其次讲解怎么进行token验证,通过拦截器设置token验证和把token设置到http报文中.主要有如下: ...
- C#版本websocket及时通信协议实现
1:Websocket有java.nodejs.python.PHP.等版本 ,我现在使用的是C3版本,服务器端是Fleck.客户端和服务器端来使用websocket的,下面开始讲解如何使用: 2:在 ...