ServiceSocket 和 ThreadPoolExecutor学习笔记
2015-11-08 00:34
417 查看
个人博客原文链接:http://www.ltang.me/2015/10/15/serviceSocket-and-threadPoolExecutor/
其中,soaTransPool是一个自定义的类,类中定义了ThreadPoolExecutor,以及实现了Runnable的静态类SoaCodecTask.
ServiceSocket监听9090端口,每当有请求到达,就创建一个socket,使用这个socket构造一个Runnable对象,即SoaCodecTask,再使用ThreadPoolExecutor来执行这个Runnable对象。也就是说,对每个请求创建一个任务,由线程池来执行这个任务。
事实上,ServiceSocket的功能就是向系统注册一个服务,然后等待客户端请求,或者从请求队列中取出Socket,至于数据的传递则由Socket完成。
上面的例子中,使用的是线程池的处理方式,接收到的请求由线程池来处理;如果是简单的单线程ServiceSocket,则可以这么写:
如果是想用多线程,就如第一个例子中那样,将socket作为参数创建一个Runnable对象,并新建一个线程并start以执行run方法。
一个任务通过execute(Runnable)方法被添加到线程池,任务就是一个Runnable类型的对象,任务的执行方法就是Runnable类型对象的run()方法。
当一个任务通过execute(Runnable)方法添加到线程池时:
如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
如果此时线程池中的数量等于corePoolSize,但是缓冲队列workQueue未满,那么任务被放入缓冲队列。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
这里的defaultHandler就是实现了RejectedExecutionHandler的一个类,它会抛出任务被拒绝的异常。
当线程池中的线程数量大于corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
上面说的,使用handler处理被拒绝的任务,查看代码如下:
这里的defaultHandler就是实现了RejectedExecutionHandler的一个类,它会抛出任务被拒绝的异常。
handler有四个选择:
ThreadPoolExecutor.AbortPolicy()
抛出java.util.concurrent.RejectedExecutionException异常
ThreadPoolExecutor.CallerRunsPolicy()
重试添加当前的任务,他会自动重复调用execute()方法
ThreadPoolExecutor.DiscardOldestPolicy()
抛弃旧的任务
ThreadPoolExecutor.DiscardPolicy()
抛弃当前的任务
ServiceSocket部分
final ServerSocket server = new ServerSocket(9090); server.setReceiveBufferSize(1024 * 4);// 设置缓冲区大小4k do { try { final Socket client = server.accept(); soaTransPool.execute(new SoaTransPool.SoaCodecTask(client)); } catch (IOException e) { //TODO e.printStackTrace(); } } while (true);
其中,soaTransPool是一个自定义的类,类中定义了ThreadPoolExecutor,以及实现了Runnable的静态类SoaCodecTask.
ServiceSocket监听9090端口,每当有请求到达,就创建一个socket,使用这个socket构造一个Runnable对象,即SoaCodecTask,再使用ThreadPoolExecutor来执行这个Runnable对象。也就是说,对每个请求创建一个任务,由线程池来执行这个任务。
事实上,ServiceSocket的功能就是向系统注册一个服务,然后等待客户端请求,或者从请求队列中取出Socket,至于数据的传递则由Socket完成。
上面的例子中,使用的是线程池的处理方式,接收到的请求由线程池来处理;如果是简单的单线程ServiceSocket,则可以这么写:
ServiceSocket server = new ServiceSocket(9090); Socket client = null; do { try { client = server.accept(); System.out.println("新增链接: " + client.getInetAddress() + ": " + client.getPort()); // ...接收、处理、发送数据 } catch (IOException e) { //TODO e.printStackTrace(); }finally{ if(client != null){ client.close(); } } } while (true);
如果是想用多线程,就如第一个例子中那样,将socket作为参数创建一个Runnable对象,并新建一个线程并start以执行run方法。
ThreadPoolExecutor部分
private int corePoolSize = 100; //线程池维护线程的最少数量 private iint maximumPoolSize = 200; //线程池维护线程的最大数量 private long keepAliveTime = 60; //线程池维护线程所允许的空闲时间 private TimeUnit unit = TimeUnit.SECOND; //空闲时间单位 private BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(50); //线程池的缓冲队列 private final ThreadFactory threadFactory = new DefaultThreadFactory("Thread Of Test"); private ExecutorService threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory); public class DefaultThreadFactory implements ThreadFactory { private final AtomicInteger threadNumber = new AtomicInteger(1); private final String name; public DefaultThreadFactory(String name) { this.name = name; } @Override public Thread newThread(Runnable r) { return new Thread(r, name + "-" + threadNumber.getAndIncrement()); } }
一个任务通过execute(Runnable)方法被添加到线程池,任务就是一个Runnable类型的对象,任务的执行方法就是Runnable类型对象的run()方法。
当一个任务通过execute(Runnable)方法添加到线程池时:
如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
如果此时线程池中的数量等于corePoolSize,但是缓冲队列workQueue未满,那么任务被放入缓冲队列。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
这里的defaultHandler就是实现了RejectedExecutionHandler的一个类,它会抛出任务被拒绝的异常。
当线程池中的线程数量大于corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
上面说的,使用handler处理被拒绝的任务,查看代码如下:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler); }
这里的defaultHandler就是实现了RejectedExecutionHandler的一个类,它会抛出任务被拒绝的异常。
handler有四个选择:
ThreadPoolExecutor.AbortPolicy()
抛出java.util.concurrent.RejectedExecutionException异常
ThreadPoolExecutor.CallerRunsPolicy()
重试添加当前的任务,他会自动重复调用execute()方法
ThreadPoolExecutor.DiscardOldestPolicy()
抛弃旧的任务
ThreadPoolExecutor.DiscardPolicy()
抛弃当前的任务
相关文章推荐
- 一些排版的笔记
- 转一个 Xcode 7 缺少 *.dylib库的解决方法
- IOS中使用像素位图(CGImageRef)对图片进行处理
- Effective C++ 笔记 第三部分 资源管理
- Find the Duplicate Number 解答
- KSImageNamed 安装后无效解决方法(试过有效)
- IOS 编程中引用第三方的方类库的方法及常见问题
- Linux-grep命令小记
- Search
- markdown 学习笔记
- QT 4.87 changes
- ubuntu 安装 swoole 和mac 安装swoole 扩展
- CocoaPods安装和使用教程
- Android读书笔记----滑动冲突的解决方式
- dwz框架实现关闭navTab刷新指定navTab的一种方案
- Oracle查看表空间使用率(包括临时表空间)
- sublime Text 2使用中的插件
- CocoaPods安装与使用
- 【Alpha】Daily Scrum Meeting第五次
- 【Alpha】Daily Scrum Meeting第五次