转载标明出处: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的更多相关文章

  1. Java 并发专题 : Executor详细介绍 打造基于Executor的Web服务器

    转载标明出处:http://blog.csdn.net/lmj623565791/article/details/26938985 继续并发,貌似并发的文章很少有人看啊~哈~ 今天准备详细介绍java ...

  2. Java 并发和多线程(一) Java并发性和多线程介绍[转]

    作者:Jakob Jenkov 译者:Simon-SZ  校对:方腾飞 http://tutorials.jenkov.com/java-concurrency/index.html 在过去单CPU时 ...

  3. Java并发性和多线程介绍

    java并发性和多线程介绍: 单个程序内运行多个线程,多任务并发运行 多线程优点: 高效运行,多组件并行.读->操作->写: 程序设计的简单性,遇到多问题,多开线程就好: 快速响应,异步式 ...

  4. Java 并发专题 : CyclicBarrier 打造一个安全的门禁系统

    继续并发专题~ 这次介绍CyclicBarrier:看一眼API的注释: /** * A synchronization aid that allows a set of threads to all ...

  5. Java并发专题

    ——参考于码农求职小助手公众号 1.并行和并发有什么区别? 1. 并行是指两个或者多个事件在同一时刻发生:而并发是指两个或多个事件在同一时间间隔发生: 2. 并行是在不同实体上的多个事件,并发是在同一 ...

  6. Java 并发专题 :FutureTask 实现预加载数据 在线看电子书、浏览器浏览网页等

    继续并发专题~ FutureTask 有点类似Runnable,都可以通过Thread来启动,不过FutureTask可以返回执行完毕的数据,并且FutureTask的get方法支持阻塞. 由于:Fu ...

  7. Java 并发专题 : Semaphore 实现 互斥 与 连接池

    继续并发方面的知识.今天介绍Semaphore,同样在java.util.concurrent包下. 本来准备通过例子,从自己实现到最后使用并发工具实现,但是貌似效果并不是很好,有点太啰嗦的感觉,所有 ...

  8. Java 并发专题 :闭锁 CountDownLatch 之一家人一起吃个饭

    最近一直整并发这块东西,顺便写点Java并发的例子,给大家做个分享,也强化下自己记忆. 每天起早贪黑的上班,父母每天也要上班,话说今天定了个饭店,一家人一起吃个饭,通知大家下班去饭店集合.假设:3个人 ...

  9. Java 并发专题 : Timer的缺陷 用ScheduledExecutorService替代

    继续并发,上篇博客对于ScheduledThreadPoolExecutor没有进行介绍,说过会和Timer一直单独写一篇Blog. 1.Timer管理延时任务的缺陷 a.以前在项目中也经常使用定时器 ...

随机推荐

  1. 第一数学归纳法 vs 第二数学归纳法 vs 良序定理

    相关: 第一数学归纳法 vs 第二数学归纳法 vs 良序定 第二数学归纳法:硬币问题和堆垛游戏 第一数学归纳法:施塔特中心的地板砖 良序原理:算术基本定理的证明 From : Mathematics ...

  2. Java GC算法 垃圾收集器

    GC算法 垃圾收集器 概述 垃圾收集 Garbage Collection 通常被称为"GC",它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. ...

  3. Unity 游戏框架搭建 (二十) 更安全的对象池

    上篇文章介绍了,只需通过实现IObjectFactory接口和继承Pool类,就可以很方便地实现一个SimpleObjectPool.SimpleObjectPool可以满足大部分的对象池的需求.而笔 ...

  4. npm常用命令及版本号浅析

    npm 包管理器的常用命令 测试环境为node>=8.1.3&&npm>=5.0.3 1, 首先是安装命令 //全局安装 npm install 模块名 -g //本地安装 ...

  5. 关于thinkphp控制器引用model里的方法的一点收获

    有时候真的是很绕,为了这一点点收获,我几乎花了一天的时间.当我弄明白了的那一刻,我.........好吧,写到这里,我发现不能换行.好吧,就这样吧,开始说正题:要想在controler从model引用 ...

  6. Katana-CookieAuthenticationMiddleware-源码浅析

    准备工作 第一步,建立一个模板项目 本文从CookieAuthenticationMiddleware入手分析,首先我们来看看哪里用到了这个中间件,打开VisualStudio,创建一个Mvc项目,然 ...

  7. nodejs a和b文件相互引用

    //取自于node中文网 http://nodejs.cn/api/modules.html 当循环调用 require() 时,一个模块可能在未完成执行时被返回. 例如以下情况: a.js: con ...

  8. [转载] MapReduce工作原理讲解

    转载自http://www.aboutyun.com/thread-6723-1-1.html 有时候我们在用,但是却不知道为什么.就像苹果砸到我们头上,这或许已经是很自然的事情了,但是牛顿却发现了地 ...

  9. JMS学习之路(一):整合activeMQ到SpringMVC 转载:http://www.cnblogs.com/xiaochangwei/p/5426639.html

    JMS的全称是Java Message Service,即Java消息服务.它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者负责接收消息.把它应用到实际的业务需求中的话我们可以 ...

  10. Liunx find的运用

    find命令 一.根据 -name 查找 find[搜索范围][搜索条件] find /root -name a1 若是模糊查询,则使用通配符 *匹配任意字符{find /root -name &qu ...