仿netty线程池简化版本
package com.hcxy.car.threadpools; import java.io.IOException;
import java.nio.channels.Selector;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.hibernate.mapping.Map; public abstract class AbstractNioSelector implements Runnable { /**
* 线程池
*/
private final Executor executor; /**
* 线程安全任务队列
*/
protected final Queue<Object[]> taskQueue = new ConcurrentLinkedQueue<Object[]>(); /**
* 线程名称
*/
protected String threadName; protected static Lock lock = new ReentrantLock();
/**
* 线程池管理对象
*/
protected NioSelectorRunnablePool selectorRunnablePool; AbstractNioSelector(Executor executor, String threadName, NioSelectorRunnablePool selectorRunnablePool) {
this.executor = executor;
this.threadName = threadName;
this.selectorRunnablePool = selectorRunnablePool;
openSelector();
} private void openSelector() {
executor.execute(this);
} public void run() {//线程开始执行
Thread.currentThread().setName(this.threadName);
while (true) {//死循环一直执行,不死循环,线程执行结束,线程就销毁了。
try {
// System.out.println("----" + this.threadName + "----run-----");
processTaskQueue();
// process();//接口,执行NioServerBoss或者NioServerWorker的process方法
} catch (Exception e) {
}
} } protected synchronized final void registerTask(Object[] o) {//外层线程执行加进去
taskQueue.add(o);
System.out.println(this.threadName + "添加任务");
} public NioSelectorRunnablePool getSelectorRunnablePool() {
return selectorRunnablePool;
} protected abstract void processTaskQueue() throws IOException;
}
package com.hcxy.car.threadpools; import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger; public class NioSelectorRunnablePool { private final AtomicInteger bossIndex = new AtomicInteger();
private NioServerBoss[] bosses;//1个NioServerBoss任务,每个任务在一个线程里面执行。 private final AtomicInteger workerIndex = new AtomicInteger();
private NioServerWorker[] workeres;//16个NioServerWorker任务,每个任务在一个线程里面执行。 public NioSelectorRunnablePool(Executor boss, Executor worker) {
initBoss(boss, 1);
initWorker(worker, Runtime.getRuntime().availableProcessors() * 2);
} private void initBoss(Executor boss, int count) {
this.bosses = new NioServerBoss[count];
for (int i = 0; i < bosses.length; i++) {
bosses[i] = new NioServerBoss(boss, "boss thread " + (i + 1), this);
}
} private void initWorker(Executor worker, int count) {
this.workeres = new NioServerWorker[2/* count */];
for (int i = 0; i < workeres.length; i++) {
workeres[i] = new NioServerWorker(worker, "worker thread " + (i + 1), this);
} /*
public static void main(String[] args) {
//创建一个线程池,可回收的,没任务就回收了。newCachedThreadPool可以很大。60秒没任务就回收。
ExecutorService pool = Executors.newCachedThreadPool();//线程池
for(int i = 1; i < 5;i++){//4个任务,一个任务运行在一个线程里面
Runnable pool.execute(new Runnable() {//没有返回值 @Override public void run() {
try { Thread.sleep(5); }
catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread name: " + Thread.currentThread().getName());
}
});
try { Thread.sleep(5); }
catch (InterruptedException e) {
e.printStackTrace();
}
}
pool.shutdown();//任务执行完就关了。
/*thread name:
pool-1-thread-1 thread name: pool-1-thread-2 thread name: pool-1-thread-1
thread name: pool-1-thread-2 线程执行完了会回收,不一定开4个线程
*/
} public synchronized NioServerWorker nextWorker() {
return workeres[Math.abs(workerIndex.getAndIncrement() % workeres.length)];
} public synchronized NioServerBoss nextBoss() {
return bosses[Math.abs(bossIndex.getAndIncrement() % bosses.length)];
}
}
package com.hcxy.car.threadpools; import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.Executor; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.hcxy.car.spring.config.chain.MyServlet; /**
* boss实现类,每一个NioServerBoss再一个线程里面
*/
public class NioServerBoss extends AbstractNioSelector{ public NioServerBoss(Executor executor, String threadName, NioSelectorRunnablePool selectorRunnablePool) {
super(executor, threadName, selectorRunnablePool);
} public synchronized void registerAcceptChannelTask(Object[] o) {
registerTask(o);
} /**
* 执行队列里的任务,一个线程执行NioServerBoss任务
*/
protected synchronized void processTaskQueue() {
for (;;) {
// System.out.println(this.threadName +",出队前任务总数为:"+this.taskQueue.size());
final Object[] task = taskQueue.poll();
if (task == null) {
break;
}
// task.run();//task是runnable元素
NioServerWorker nextworker = getSelectorRunnablePool().nextWorker();// 通过线程管理对象获取一个worker(runnable任务对象),
// 注册新客户端接入任务,将新的连接请求交给worker。
nextworker.registerNewChannelTask(task);// 往别的任务队列里面加任务
}
}
}
package com.hcxy.car.threadpools; import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.Executor; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.hcxy.car.spring.config.chain.MyServlet;
import com.hcxy.car.util.CommomUtil;
/**
* worker实现类,每一个NioServerWorker再一个线程里面
*/
public class NioServerWorker extends AbstractNioSelector{ public NioServerWorker(Executor executor, String threadName, NioSelectorRunnablePool selectorRunnablePool) {
super(executor, threadName, selectorRunnablePool);
} public synchronized void registerNewChannelTask(Object[] o){
registerTask(o);
} /**
* 执行队列里的任务
如果synchronized加在一个类的普通方法上,那么相当于synchronized(this)。
如果synchronized加载一个类的静态方法上,那么相当于synchronized(Class对象)。
*/
protected synchronized void processTaskQueue() {
for (;;) {
// System.out.println(this.threadName +",出队前任务总数为:"+this.taskQueue.size());
final Object[] task = taskQueue.poll();
if (task == null) {
break;
}
download((HttpServletRequest)task[0],(HttpServletResponse)task[1]);
// task.run();//task是runnable元素
}
} //只能在servlet线程中返回流
public synchronized String download(HttpServletRequest request, HttpServletResponse response) { // version是路径
System.out.println("--------------------------1111------------------------------");
String fileName = "upload\\TBOX\\300\\20180522105038\\123.rar";
String name = fileName.substring(fileName.lastIndexOf("\\") + 1);
if (fileName != null) {
String realPath="";
try {
realPath = "D:\\eclipsworksapce1\\upgrade\\src\\main\\webapp";//request.getSession().getServletContext().getRealPath("/");
} catch (Exception e2) {
System.out.println("error");
e2.printStackTrace();
}
System.out.println("--------------------------22222------------------------------");
File file = new File(realPath, fileName);
if (file.exists()) {
response.setContentType("application/force-download");//
response.setHeader("content-type", "application/octet-stream");
response.addHeader("Content-Disposition", "attachment;fileName=" + name);// 设置文件名
response.setHeader("Connection","Keep-Alive");
byte[] buffer = new byte[5*1024 * 1024];
FileInputStream fis = null;
BufferedInputStream bis = null;
System.out.println("--------------------------33333------------------------------");
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
System.out.println("--------------------------4444------------------------------");
while (i != -1) {
try {
os.write(buffer, 0, i);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
i = bis.read(buffer);
System.out.println("--------------正在写入----------------i="+i);
}
System.out.println("--------------download----------------success");
try {
// apiTboxService.saveDownloadfile("", "tttttttttt", fileName,CommomUtil.DateFormat(),"download",CommomUtil.servernum,"success");
} catch (Exception e1) {
e1.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
try {
// apiTboxService.saveDownloadfile("", "tttttttttt", fileName,CommomUtil.DateFormat(),"download",CommomUtil.servernum,e.toString());
} catch (Exception e1) {
e1.printStackTrace();
}
System.out.println("download---error");
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
return "ss";
}
}
package com.hcxy.car.threadpools; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.hcxy.car.spring.config.chain.MyServlet; /**
* 服务类
*/
public class ServerBootstrap { private NioSelectorRunnablePool selectorRunnablePool; public ServerBootstrap(NioSelectorRunnablePool selectorRunnablePool) {
this.selectorRunnablePool = selectorRunnablePool;
} public synchronized void bind(Object[] o){//外层线程调用
try {
//获取一个boss线程
NioServerBoss nextBoss = selectorRunnablePool.nextBoss();
//向boss注册一个ServerSocket通道
nextBoss.registerAcceptChannelTask(o);
// MyServlet o1 = (MyServlet)o[2];
// o1.doGet((HttpServletRequest)o[0],(HttpServletResponse)o[1]);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.hcxy.car.threadpools; import java.net.InetSocketAddress;
import java.util.concurrent.Executors; public class Threadpools {
public static ServerBootstrap bootstrap = null;
public static void begin() {
// 管理线程池的,初始化2个线程池,一个boss一个work线程池,里面的线程一直死循环的run,
NioSelectorRunnablePool nioSelectorRunnablePool = new NioSelectorRunnablePool(Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
// 获取服务类
bootstrap = new ServerBootstrap(nioSelectorRunnablePool);
// final String ss = "Start----main";
// 绑定端口
// for(int i = 0;i<9;i++) {
// bootstrap.bind(ss+i);
// }
}
}
仿netty线程池简化版本的更多相关文章
- Vista 及后续版本的新线程池
在上一篇的博文中,说了下老版本的线程池,在Vista之后,微软重新设计了一套线程池机制,并引入一组新的线程池API,新版线程池相对于老版本的来说,它的可控性更高,它允许程序员自己定义线程池,并规定线程 ...
- Linux网络通信(线程池和线程池版本的服务器代码)
线程池 介绍 线程池: 一种线程使用模式.线程过多会带来调度开销,进而影响缓存局部性和整体性能.而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务.这避免了在处理短时间任务时创建与销毁线程的 ...
- jdk线程池ThreadPoolExecutor工作原理解析(自己动手实现线程池)(一)
jdk线程池ThreadPoolExecutor工作原理解析(自己动手实现线程池)(一) 线程池介绍 在日常开发中经常会遇到需要使用其它线程将大量任务异步处理的场景(异步化以及提升系统的吞吐量),而在 ...
- (Java 多线程系列)Java 线程池(Executor)
线程池简介 线程池是指管理同一组同构工作线程的资源池,线程池是与工作队列(Work Queue)密切相关的,其中在工作队列中保存了所有等待执行的任务.工作线程(Worker Thread)的任务很简单 ...
- MySQL线程池的引入可以提高我们的MySQL的性能
支持线程池的版本:MySQL 企业版本,MySQL percona的分支 MariDB 的版本.我们知道我们的MySQL 语句是不支持硬解析的,没有无SQL 解析 cache.每个连接对应一个线程,我 ...
- Executor线程池的简单使用
我们都知道创建一个线程可以继承Thread类或者实现Runnable接口,实际Thread类就是实现了Runnable接口. 到今天才明白后端线程的作用:我们可以开启线程去执行一些比较耗时的操作,类似 ...
- python 并发专题(二):python线程以及线程池相关以及实现
一 多线程实现 线程模块 - 多线程主要的内容:直接进行多线程操作,线程同步,带队列的多线程: Python3 通过两个标准库 _thread 和 threading 提供对线程的支持. _threa ...
- netty的线程池-----揭示了使用两个线程池的原因
线程模型是Netty的核心设计,设计地很巧妙,之前项目中有一块处理并发的设计和Netty的Eventloop单线程设计类似,效果得到了实证. Netty5的类层次结构和之前的版本变化很大,网上也有很多 ...
- Netty源码解析一——线程池模型之线程池NioEventLoopGroup
本文基础是需要有Netty的使用经验,如果没有编码经验,可以参考官网给的例子:https://netty.io/wiki/user-guide-for-4.x.html.另外本文也是针对的是Netty ...
随机推荐
- 第六篇:二维数组的传输 (host <-> device)
前言 本文的目的很明确:介绍如何将二维数组传递进显存,以及如何将二维数组从显存传递回主机端. 实现步骤 1. 在显存中为二维数组开辟空间 2. 获取该二维数组在显存中的 pitch 值 (cudaMa ...
- 有Thread1、Thread2、Thread3、Thread4四条线程分别统计C、D、E、F四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现?
利用java.util.concurrent包下的CountDownLatch(减数器)或CyclicBarrier(循环栅栏) 转自:http://www.cnblogs.com/westward/ ...
- Win32控制台中使用定时器的方法
在MFC中用OnTimer()函数就可以很方便的实现定时事件,但在Win32控制台工程中没有消息循环,MSDN里也不推荐把SetTimer()用在Console Applications里. 同理,在 ...
- python 自己定义异常
通过创建一个新的异常类,就可以命名自己的异常,异常应该是典型的继承自Exception类 例如: # 定义了一个自己的异常类,可在适当时候通过raise来触发它class ExError(Except ...
- CLR via 笔记 5.3 值类型的装箱和拆箱
1.装箱 为了将一个值类型转换成一个引用类型,要使用一个名为装箱(Boxing)的机制. 1.在托管堆中分配好内存.分配的内存量是值类型的各个字段需要的内存量加上托管堆的所有对象都有的两个额外成员(类 ...
- php composer,update-ca-trust
安装 ComposerComposer 需要 PHP 5.3.2+ 才能运行. $ curl -sS https://getcomposer.org/installer | php这个命令会将 com ...
- linux日志自动分割shell
随着服务器运行时间不断增加,各种日志文件也会不断的增长,虽然硬盘已经是白菜价了,但是如果当你看到你的一个日志文件达到数十G的时候是什么感想?下面的脚本实现了如下功能: 自动对日志文件进行分割 对分割后 ...
- JavaScript自定义函数
js对象转成用&拼接的请求参数(转) var parseParam=function(param, key){ var paramStr=""; if(param inst ...
- 剑指Offer——两个链表的第一个公共结点
题目描述: 输入两个链表,找出它们的第一个公共结点. 分析: 设置两个指针,分别从两个链表的头部开始往后遍历. 谁遍历完自己本身的,就从另一个链表开始遍历,这样大家到达第一个公共结点的时候便会相遇. ...
- Spark Standalone Mode 单机启动Spark -- 分布式计算系统spark学习(一)
spark是个啥? Spark是一个通用的并行计算框架,由UCBerkeley的AMP实验室开发. Spark和Hadoop有什么不同呢? Spark是基于map reduce算法实现的分布式计算,拥 ...