当前位置: 首页 > news >正文

辽阳建设银行网站公司网站开发费用济南兴田德润简介图片

辽阳建设银行网站,公司网站开发费用济南兴田德润简介图片,wordpress 小视频模板,网业协同机制目录 一、线程池 1. 构建线程池的类 2. 创建任务 3. 执行任务 测试 二、URL编码 解决方案 测试 三、如何接收客户端发送的全部信息 解决方案 测试 四、作业 1. 了解工厂模式 2. 了解反射技术 一、线程池 昨天使用了数据库连接池#xff0c;我们了解了连接池的优…目录 一、线程池 1. 构建线程池的类 2. 创建任务 3. 执行任务 测试 二、URL编码 解决方案 测试 三、如何接收客户端发送的全部信息 解决方案 测试 四、作业 1. 了解工厂模式 2. 了解反射技术 一、线程池 昨天使用了数据库连接池我们了解了连接池的优点那么也可以使用线程池来管理线程 java自带的线程池的参数有 核心线程数最大线程数线程活跃时间时间单位任务队列线程工厂拒绝策略 为了学习了解线程池我们先手写一个简单的线程池只需要做到核心线程可重复利用就行 1. 构建线程池的类 属性核心线程数任务队列 方法获取线程静态代码块执行任务需要的参数线程任务 Runnable 为了避免创建多个对象还需要设置单例模式 package com.shao.net;import java.util.concurrent.LinkedBlockingQueue;public class ThreadPool {// 定义一个成员静态变量存储单例对象private static ThreadPool instance;// 线程池核心线程数private final static int MAX_THREAD_NUM 10;// 存放任务的队列private static final LinkedBlockingQueueRunnable taskQueue new LinkedBlockingQueue();static {for (int i 0; i MAX_THREAD_NUM; i) {final int finalI i;new Thread(new Runnable() {Overridepublic void run() {/*** 线程池的线程从队列中取出任务这时线程不在临界区了自动释放锁然后执行任务当执行完任务后* 因为是while循环所以会在 synchronized (taskQueue) 等待* 当锁释放后并且当前线程被唤醒时会尝试获取锁* 如果获取到锁会进入临界区如果队列中有任务则取出然后执行任务如果没有则等待* 等待下次获取到锁会继续从上次进入等待态的位置继续往下执行也就是 taskQueue.wait() 开始往下执行* */while (true) {Runnable task null;synchronized (taskQueue) {System.out.println(线程 finalI 准备完成);// 队列为空等待while (taskQueue.isEmpty()) {try {taskQueue.wait(); // 使当前线程等待释放锁} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(线程 finalI 开始执行);// 从队列中取出任务task taskQueue.poll();}if (task ! null) {// 执行任务task.run();}}}}).start();}}// 私有化构造函数private ThreadPool() {}// 获取对象public static ThreadPool getInstance() {synchronized (ThreadPool.class) {if (instance null) {instance new ThreadPool();}return instance;}}public void execute(Runnable task) {// 当方法被调用时会尝试获取锁如果获取到锁则将任务加入队列并唤醒等待的线程synchronized (taskQueue) {taskQueue.add(task);taskQueue.notify();}} }2. 创建任务 这里的任务是之前线程执行的代码我们把需要线程执行的任务放到一个类里然后实现Runnable  package com.shao.net;import java.io.IOException; import java.io.InputStream; import java.io.OutputStream;public class MyTask implements Runnable {private InputStream is;private OutputStream os;public MyTask(InputStream is, OutputStream os) {this.is is;this.os os;}Overridepublic void run() {// 定义一个字节数组存放客户端发送的请求信息byte[] bytes new byte[1024];// 读取客户端发送的数据返回读取的字节数int len 0;try {len is.read(bytes);if (len -1) {return;}// 将读取的字节数组转换为字符串String msg new String(bytes, 0, len);// 调用HttpRequest类解析请求信息HttpRequest httpRequest new HttpRequest(msg);// 拼接请求的静态资源的路径// 路径是相对路径从模块的根路径开始String filePath webs/ httpRequest.getRequestModule();HttpResponse httpResponse new HttpResponse(os, httpRequest);// 响应数据httpResponse.response(filePath);} catch (IOException e) {e.printStackTrace();}} }3. 执行任务 初始化线程池来一个用户连接时就创建一个任务然后交给线程池线程池取出一条线程执行任务的 run 方法 package com.shao.net;import java.io.*; import java.net.ServerSocket; import java.net.Socket;public class Tomcat {// 初始化线程池ThreadPool threadPool ThreadPool.getInstance();public Tomcat() {ServerSocket ss null;try {ss new ServerSocket(8080);while (true) {// 调用accept()方法阻塞等待直到有客户端连接到服务器返回一个Socket对象用于与该客户端通信Socket socket ss.accept();System.out.println(客户端连接成功);// 获取Socket对象的输入流用于读取客户端发送的数据InputStream is socket.getInputStream();// 获取Socket对象的输出流用于向客户端发送数据OutputStream os socket.getOutputStream();// 创建一个任务对象将输入输出流作为参数传过去MyTask myTask new MyTask(is, os);// 把任务作为参数传递给ThreadPool的execute()方法启动一个线程执行MyTask对象中的run()方法threadPool.execute(myTask);}} catch (IOException e) {e.printStackTrace();} finally {//关闭连接通道try {ss.close();} catch (IOException e) {e.printStackTrace();}}} }测试 二、URL编码 在HTTP请求中如果参数包含中文字符会进行URL编码以避免乱码或传输错误。URL编码是一种将URL中的非ASCII字符如中文字符转换为可以在Web浏览器和服务器之间传输的格式的过程。 URL编码会将非ASCII字符转换为十六进制编码以便于在HTTP请求中安全传输。 ‌URL编码的基本原理‌ URL编码将非ASCII字符如中文字符转换为%后跟两位十六进制数字的形式。例如空格在URL编码中通常被转换为%20。对于中文字符它们会被转码为以%E开头后面跟着若干位十六进制数字的字符串。 解决方案 在接收到请求信息后先进行解码然后再解析信息 URLDecoder.decode(需要解码的字符串, 字符集或编码方式) 在 MyTask 类中添加 测试 三、如何接收客户端发送的全部信息 目前我们的 Tomcat 最多只能一次接收 1KB因为定义的字节数组只有1024个字节 但是如果客户端发送的请求参数非常非常多呢超过了 1024 个字节了怎么办 把字节数组定义的大一点不行的因为网络传输一次最多传输 8KB超过 8KB 就会分批传输接收参数时也需要分批接收 那怎么判断参数已经接收完 参数有很多一般是使用POST方法而POST方法的请求头有 Content-Length 的字段表示请求体的总长度 我们来试一下打印一下请求的参数信息 这里可以看到 Content-Length 的值是 26表示请求体的参数长度为26字节图中显示参数的长度为 25因为解析后没有显示参数连接符   我们来使用 Apipost 来压力测试一下参数很多是什么样子 可以看到只读取到了一部分 出师表 的内容而且还有乱码这是因为没有完整读取一个 汉字的字节UTF-8 编码中一个汉字需要 3 个字节 解决方案 package com.shao.net;import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLDecoder; import java.util.HashMap; import java.util.Map; import java.util.Set;public class MyTask implements Runnable {private InputStream is;private OutputStream os;private int totalLength;private StringBuilder sb;public MyTask(InputStream is, OutputStream os) {this.is is;this.os os;}Overridepublic void run() {// 定义一个字节数组存放客户端发送的请求信息byte[] bytes new byte[1024];// 读取客户端发送的数据返回读取的字节数int len 0;try {// 第一次读取请求信息len is.read(bytes);if (len -1) {return;}// 将读取的字节数组转换为字符串String msg new String(bytes, 0, len);// 调用HttpRequest类解析请求信息HttpRequest httpRequest new HttpRequest(msg);/** 如果已读取的数据长度等于请求体的总长度并且请求方法是 POST说明请求体可能还没有读取完需要读取剩余的数据* */if (bytes.length len POST.equals(httpRequest.getRequestMethod())) {// 创建一个StringBuilder对象用于拼接请求信息sb new StringBuilder();sb.append(msg);// 获取 POST 请求方法中的请求体的总长度String length httpRequest.getRequestHeaderParams().get(Content-Length);if (length ! null) {totalLength Integer.parseInt(length);}// 调用方法读取剩余的请求体数据msg getNotReadMsg(httpRequest, bytes, msg);}// 把请求信息进行URL解码然后根据 UTF-8 进行编码String decodedMsg URLDecoder.decode(msg, utf-8);// 调用HttpRequest类解析请求信息httpRequest new HttpRequest(decodedMsg);// 拼接请求的静态资源的路径// 路径是相对路径从模块的根路径开始String filePath webs/ httpRequest.getRequestModule();HttpResponse httpResponse new HttpResponse(os, httpRequest);// 响应数据httpResponse.response(filePath);} catch (IOException e) {e.printStackTrace();}}/*** 读取剩余的请求体数据*/private String getNotReadMsg(HttpRequest httpRequest, byte[] bytes, String msg) throws IOException {int len;// 获取请求的参数HashMapString, String requestBodyParams httpRequest.getRequestBodyParams();// 请求参数的数量int size requestBodyParams.size();// 计算第一次读取到的请求体中参数的长度SetMap.EntryString, String entries requestBodyParams.entrySet();int partLength 0;for (Map.EntryString, String entry : entries) {partLength (entry.getKey() entry.getValue()).length();}// 减去第一次读取到的请求体中参数的长度如果存在多个参数需要考虑到 的个数if (size 1) {totalLength - (partLength (size - 1));} else {totalLength - partLength;}// 判断是否还有数据没有读完while (totalLength 0) {// 第二次读取请求信息len is.read(bytes);// 如果读取的字节数大于0表示读取到数据了if (len 0) {// 将读取的字节数组转换为字符串msg new String(bytes, 0, len);// 拼接字符串sb.append(msg);// 减去读取的字节数totalLength - len;} else {break;}}// 转成字符串格式返回return sb.toString();} }测试 可以看出已经全部读取到了第二个参数也读取到了 四、作业 1. 了解工厂模式 优化 Dao现在在 Service 层调用Dao层都要 new 一下这样就比较占内存比如调用的都是 UserDao那么只需要创建一次 UserDao 的对象就行了 2. 了解反射技术 优化 Servlet 通过配置文件可以动态的创建 Servlet 对象
http://www.w-s-a.com/news/197218/

相关文章:

  • 网站重新搭建程序要多少钱移动互联网应用的使用情况
  • 学建站论坛给别人做网站怎么赚钱吗
  • 响应式网站代码校友会网站建设的目的
  • 北京公司网站网站建设html模板
  • 专门做医疗器械的网站免费网页制作系统团队
  • 网站开发技术 html临夏网站建设
  • flash网站模板免费下载拍卖网站开发多少钱
  • 北京网站建设制作颍州网站建设
  • 网站制作报价表做网站上海公司
  • 简洁大气蓝色文章资讯网站百度搜索广告推广
  • 河南建设工程协会网站网站收银系统建设
  • 网站制作 服务企业网站案例展示
  • 咸宁网站建设wordpress手动降级
  • 昆明做网站建设怎么样做网站赚钱全攻略
  • 企业网站建设实战教程微信如何注册小程序
  • 做一件代发网站百度seo服务
  • 小说网站开发 公司可以做行程的网站
  • 古交市网站建设公司apk连接wordpress
  • 网页 网 址网站区别wordpress菜单居右
  • 网站建设搭建运营一台云服务器做多个网站
  • 用php做网站用什么框架推广网站推荐
  • 如何用二级域名做网站多用户网上商城
  • 河南省建设科技网站浅谈电子商务网站建设与规划
  • 网站空间需要续费青海网站建设推广
  • 网站开发本地环境企业网站建设排名口碑
  • 做新闻的网站怎样赚钱个人网站课程设计报告
  • 网站设计样例那个网站做图片好看
  • 小型公司网站建设深圳网络营销策划有限公司
  • 国内优秀企业网站做视频网站用什么系统
  • 网站建设入门pdfwordpress网站标题