java I/O 学习笔记2 ,线程池
来源:互联网 发布:怎么登陆淘宝卖家中心 编辑:程序博客网 时间:2024/05/02 00:06
线程池:就是为了解决一客户端一线程的过度资源消耗问题,而在预先定义好线程的数量,而当有新的请求接入时,就将这个新的请求接入封装成一个task丢到线程池中处理,在这种情况下,资源的使用是可控的。
同样,以一个客户端发送消息,服务器接收并且返回消息的例子作为分析。
思路:
Server端:
1. server端使用ServerSocket的一个实例,绑定端口并且监听,
2. 创建一个线程池,指定线程池属性
3. ServerSocket实例将接收到的每个socket单独封装成一个task,
4. 将task丢到线程池中处理
Client端:
1. 新建一个Socket实例,并且连接到server,(建议将这个Socket封装成一个单独的类),
2. 获取Socket的输入流和输出流,收发信息
Server端代码:三部分组成,ExecutorPoolServer.java,主函数入口
;ExecutePoolServerHandler.java,用于封装线程池的类;BIOSocketHandler.java;负责到客户端的Soket连接;
代码:
ExecutePoolServer.java
package learningNote.IO;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;public class ExecutePoolServer { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub int port=8090; ServerSocket ss=new ServerSocket(port); ExecutePoolServerHandler esph=new ExecutePoolServerHandler();//创建线程池 while(true){ System.out.println(esph.activtedThreadCount());//查看这个线程池上面的活跃线程数 Socket s=ss.accept(); esph.execute(new BIOSocketHandler(s));//将新的请求连接放入线程池中 } }}
ExecutePoolServerHandler.java
package learningNote.IO;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.ExecutorService;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class ExecutePoolServerHandler{ private ExecutorService es; public ExecutePoolServerHandler() { // TODO Auto-generated constructor stub es=new ThreadPoolExecutor(1, 2, 1000, TimeUnit.MICROSECONDS, new ArrayBlockingQueue<Runnable>(10));//这个构造函数的说明可以查阅:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html#ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue) } public void execute(Runnable task){ es.execute(task);//这里的参数必须是Runnable类型的实例,因为jvm创建的线程会根据此来调用run()方法 } public int activtedThreadCount(){ return Thread.activeCount(); }}
BIOSocketHandler.java
package learningNote.IO;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;public class BIOSocketHandler implements Runnable{ private Socket s; public BIOSocketHandler(Socket s) { // TODO Auto-generated constructor stub this.s = s; } @Override public void run() { // TODO Auto-generated method stub try (BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream()));//获取socket的输入流 PrintWriter out=new PrintWriter(s.getOutputStream(),true);//获取socket的输出流,并且设置自动刷新缓冲区 ){ //读取输入消息并打印 String message=" "; while(true){ //读取输入消息 while(true){ String temp=in.readLine(); if(temp.equals("ok")){ break; } message+=temp+"\n"; } //打印收到的消息 System.out.print(message); //返回消息 String now=new java.util.Date().toString(); out.println(now+" "+message+"ok"); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); System.exit(1); } }}
- 当线程池中的线程(指定的最大线程)已经全部用完之后,新的task会被放到ArrayBlockingQueue,这时一个顺序队列,属于先进先出的一种能够算法.,就是最先进入的元素也会最先出队。
- 注意到server 端socket会一直存在直到client端的socket被关闭,也就是说,会导致线程的一直占用
- 注意InputStream中的read方法,这个方法本身也会引起阻塞因为它不会立即被返回直到:数据可用(input data is available ,),数据读取完毕(end of the file is detected ),或者抛出错误(throw a exception)。..前两者的情况不太清楚…因为这样岂不是会被返回两次??
OutputStream中的write方法,也会造成阻塞,(这很大程度上与tcp/ip缓冲区以及网络状况有关)..
Client端代码:
ExecutePoolClient .java
package learningNote.IO;import java.io.IOException;import java.net.Socket;import java.net.UnknownHostException;public class ExecutePoolClient { public static void main(String[] args) throws UnknownHostException, IOException { // TODO Auto-generated method stub Socket s=new Socket("127.0.0.1",8090); new Thread(new BIOClientHandler(s)).start(); }}
BIOClientHandler.java
package learningNote.IO;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;public class BIOClientHandler implements Runnable { private Socket s; public BIOClientHandler(Socket s) { // TODO Auto-generated constructor stub this.s=s; } @Override public void run() { // TODO Auto-generated method stub try(BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream())); BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); PrintWriter out=new PrintWriter(s.getOutputStream(),true)){ while(true){ //从控制台读取输入 String message=" "; while(true){ String temp=br.readLine(); if(temp.equals("ok"))break; message+=temp+"\n"; } //发送消息 out.println(message+"ok"); //读取消息 String body=" "; while(true){ String temp=in.readLine(); if(temp.equals("ok"))break; body+=temp+"\n"; } System.out.print(body); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
0 0
- java I/O 学习笔记2 ,线程池
- Java I/O学习笔记
- Java I/O学习笔记
- 【Java学习笔记】I/O
- java I/O 学习笔记
- Java I/O 学习笔记(7) new I/O
- java基础——java I/O学习笔记2
- JavaSE基础学习笔记-Java I/O系统2-File
- java i/o黑马程序员学习笔记(2)
- Java I/O 学习笔记(2) 基本输入输出流
- java学习笔记-I/O篇(2):BufferedInputStream
- JAVA I/O系统学习笔记-部分
- java中I/O流学习笔记
- java I/O流学习笔记
- 关于java I/O流学习笔记
- java I/O学习笔记3 ---NIO
- 【Java学习笔记】I/O实例
- java学习笔记-I/O篇(1)
- 开源免费,捷微H5活动平台(微砍价、九宫格、斧头帮、摇一摇送卡券) h5huodong.com
- 栏目列表调用的是顶级栏目,如果需要子栏目页面展开父栏目分类则可以用下边的代码
- 浅谈跨进程传递的数据
- HDU 1992
- android getLocationInWindow()的小秘密
- java I/O 学习笔记2 ,线程池
- Miller-Rabin 素数测试
- maven打war包以及maven工程调用别人生成的jar包
- CHtmlView 处理/禁止 JavaScript 脚本错误!
- 高级并发学习之Samphere同步工具学习
- 怎么使用 JavaScript 将网站后台的数据变化实时更新到前端?
- javascript中的window.location.search方法简介
- 利用HttpURLConnection发送post请求上传多个文件
- LeetCode 3Sum Closest