java scoket Blocking 阻塞IO socket通信二
在上面一节中,服务端收到客户端的连接之后,都是new一个新的线程来处理客户端发送的请求,每次new 一个线程比较耗费系统资源,如果100万个客户端,我们就要创建100万个线程,相当的
耗费系统的资源,服务器是没有办法支持这样多的客户端进行连接的
我们可以采用线程池的方式来实现:提高
package bhz.bio2; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException; public class Client { final static String ADDRESS = "127.0.0.1";
final static int PORT =8765; public static void main(String[] args) {
Socket socket = null;
BufferedReader in = null;
PrintWriter out = null;
try {
socket = new Socket(ADDRESS, PORT);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true); out.println("Client request"); String response = in.readLine();
System.out.println("Client:" + response); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if(in != null){
try {
in.close();
} catch (Exception e1) {
e1.printStackTrace();
}
}
if(out != null){
try {
out.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
if(socket != null){
try {
socket.close();
} catch (Exception e3) {
e3.printStackTrace();
}
}
socket = null;
} } }
package bhz.bio2; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; public class HandlerExecutorPool { private ExecutorService executor;
public HandlerExecutorPool(int maxPoolSize, int queueSize){
this.executor = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors(),
maxPoolSize,
120L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(queueSize));
} public void execute(Runnable task){
this.executor.execute(task);
} }
package bhz.bio2; import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket; public class Server { final static int PORT = 8765; public static void main(String[] args) {
ServerSocket server = null;
BufferedReader in = null;
PrintWriter out = null;
try {
server = new ServerSocket(PORT);
System.out.println("server start");
Socket socket = null;
HandlerExecutorPool executorPool = new HandlerExecutorPool(50, 1000);
while(true){
socket = server.accept();
executorPool.execute(new ServerHandler(socket));
} } catch (Exception e) {
e.printStackTrace();
} finally {
if(in != null){
try {
in.close();
} catch (Exception e1) {
e1.printStackTrace();
}
}
if(out != null){
try {
out.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
if(server != null){
try {
server.close();
} catch (Exception e3) {
e3.printStackTrace();
}
}
server = null;
} } }
package bhz.bio2; import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket; public class ServerHandler implements Runnable { private Socket socket;
public ServerHandler (Socket socket){
this.socket = socket;
} @Override
public void run() {
BufferedReader in = null;
PrintWriter out = null;
try {
in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
out = new PrintWriter(this.socket.getOutputStream(), true);
String body = null;
while(true){
body = in.readLine();
if(body == null) break;
System.out.println("Server:" + body);
out.println("Server response");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(in != null){
try {
in.close();
} catch (Exception e1) {
e1.printStackTrace();
}
}
if(out != null){
try {
out.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
if(socket != null){
try {
socket.close();
} catch (Exception e3) {
e3.printStackTrace();
}
}
socket = null;
} } }
阻塞模式:列如客户端请求服务器的数据,服务器如果返回10个字节的数据给客户端,如果网络较差,客户端就必须一致等待着指定10个字节发送完成,就一直阻塞着
非阻塞模式nio模式:应用程序无需等待可以直接获得服务器端的数据,无效等待,线程不会阻塞
阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。
同步和异步:
A. 同步
所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。
按照这个定义,其实绝大多数函数都是同步调用(例如sin isdigit等)。
但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。
最常见的例子就是 SendMessage。
该函数发送一个消息给某个窗口,在对方处理完消息之前,这个函数不返回。
当对方处理完毕以后,该函数才把消息处理函数所返回的值返回给调用者。
B. 异步
异步的概念和同步相对。
当一个异步过程调用发出后,调用者不会立刻得到结果。
实际处理这个调用的部件是在调用发出后,
通过状态、通知来通知调用者,或通过回调函数处理这个调用。
以 Socket为例,
当一个客户端通过调用 Connect函数发出一个连接请求后,调用者线程不用等待结果,可立刻继续向下运行。
当连接真正建立起来以后,socket底层会发送一个消息通知该对象。
C. 三种返回结果途径
执行部件和调用者可以通过三种途径返回结果:
a. 状态、
b. 通知、
c. 回调函数。
总结:阻塞是针对当前的线程
同步和异步:值得的函数的返回值,同步调用者会一直等待值得服务器返回值,异步是调用该函数不会立刻得到返回值,服务器通知、或者回调的方法通知调用者
getInputStream和getOutputStream都是同步并且阻塞的模型
jdk1.7版本之前nio是同步非阻塞的,在1.7以后实现了异步非阻塞的
java scoket Blocking 阻塞IO socket通信二的更多相关文章
- java scoket Blocking 阻塞IO socket通信一
package bhz.bio; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; p ...
- java scoket Blocking 阻塞IO socket通信四
记住NIO在jdk1.7版本之前是同步非阻塞的,以前的inputsream是同步阻塞的,上面学习完成了Buffer现在我们来学习channel channel书双向的,以前阻塞的io的inputstr ...
- java scoket Blocking 阻塞IO socket通信三
在NIO同步非阻塞的场景中和原来同步阻塞最大的却别就是引入了上面的Buffer对象,现在我们来学校上面的BUffer对象 我们来看看程序的代码: package bhz.nio.test; impor ...
- Java与C之间的socket通信
最近正在开发一个基于指纹的音乐检索应用,算法部分已经完成,所以尝试做一个Android App.Android与服务器通信通常采用HTTP通信方式和Socket通信方式.由于对web服务器编程了解较少 ...
- java多线程实现多客户端socket通信
一.服务端 package com.czhappy.hello.socket; import java.io.IOException; import java.net.InetAddress; imp ...
- Delphi和JAVA用UTF-8编码进行Socket通信例子
最近的项目(Delphi开发),需要经常和java语言开发的系统进行数据交互(Socket通信方式),数据编码约定采用UTF-8编码. 令我无语的是:JAVA系统那边反映说,Delphi发的数据他们收 ...
- java与c/c++进行socket通信
比如Server端只接收一个结构Employee,定义如下: struct UserInfo { char UserName[20]; int UserId; }; struct Employ ...
- java nio--采用Selector实现Socket通信
server: /** * 选择器服务端 * Created by ascend on 2017/6/9 9:30. */ public class SelectorServer { // publi ...
- 使用Socket通信(二)
这个socket有梗,主要是服务器端有梗,可能大家会碰到同样的问题,网上查了好久,这里分享一下解决办法.首先在第一个module建一个类SimpleServer,这个类就是服务端,建好之后在代码左边有 ...
随机推荐
- CELF算法原理
影响力传播模型中的独立层叠模型(independent cascading model,IC模型),影响力传播过程中,种子的影响力具备子模性(submodularity),即种子的边际影响力增量会呈现 ...
- 【JVM】如何理解强引用、软引用、弱引用、虚引用?
整体架构 强引用 强引用是默认支持,当内存不足的时候,JVM开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会回收对象. 强引用是最常见的普通对象引用,只要还有强引用指向对象,对象就存活,垃圾回 ...
- JAVASE(十三) 异常处理
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.异常体系结构 说明: |-----Throwable |-----Error :没针对性代码进行 ...
- SpringBoot 之 拦截配置 与SpringCloud
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.SpringBoot 与 SpringMVC 的区别? SpringMVC是基于Spring的MV ...
- HTML中块级行级元素小分类
行内元素列表: <a>标签可定义锚 <abbr>表示一个缩写形式 <acronym>定义只取首字母缩写 <b>字体加粗 <bdo>可覆盖默认 ...
- Java实现蓝桥杯基础练习特殊回文数
基础练习 特殊回文数 时间限制:1.0s 内存限制:512.0MB 提交此题 锦囊1 锦囊2 问题描述 123321是一个非常特殊的数,它从左边读和从右边读是一样的. 输入一个正整数n, 编程求所有这 ...
- java实现第九届蓝桥杯三角形面积
三角形面积 小明最近在玩一款游戏.对游戏中的防御力很感兴趣. 我们认为直接影响防御的参数为"防御性能",记作d,而面板上有两个防御值A和B,与d成对数关系,A=2^d,B=3^d( ...
- python自学Day04(自学书籍python编程从入门到实践)
第5章 if 语句 5.1 一个简单的示例 使用前面的解析列表构建一个0-9的数值列表. 判断0是否在列表中,如果在输出 0在列表A中 A = [i for i in range(0,10)] if ...
- Javascript:跳转到指定页面
<div> <input type="text" id="jumpPage"/> <input type="button ...
- DedeCms 标签中channelartlist设置属性标签样式的方法
实现的效果如下: {dede:channelartlist typeid='6' row='3' currentstyle='current'} <li class='{dede:field.c ...