java socket 回调函数_请问Java网络编程如何在不使用多线程的情况下实现异步返回?...
我指的是在不使用多线程的情况下进行并发处理
具体的情况是,在不使用多线程的情况下,服务器侦听某个端口,在有连接进来的时候会调用某个函数对此连接进行处理,但是由于处理的过程可能会比较长,为了不让后面连接的用户等待,需要此函数能异步返回,而不是阻塞在这个函数。
之所以希望不使用多线程,是因为考虑到同时连接的用户数会比较多,如果用多线程的话,线程创建,销毁和切换的开销会太大。虽然可以使用线程池,但是这样只是省去了创建和销毁线程的开销,线程切换的开销还是会存在,而且线程的数目也不好确定。
.NET中的Socket类有个方法是BeginReceive,这个方法中可以定义一个回调函数,在调用BeginReceive之后,回调函数会被调用,而BeginReceive可以立即返回,因此在不使用多线程的情况下可以实现并发处理。
我要的就是这种效果,请问在Java中怎么实现?
我找了些资料,里面提到用ServerSocketChannel,即NIO可以实现非阻塞,但是我实验了一下,好像不行。
代码如下:
package snake.test.channel;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
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;
class Server {
public static void main(String[] args) {
Reactor re = null;
try {
re = new Reactor(6656);
re.run();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Reactor implements Runnable {
final Selector selector;
final ServerSocketChannel serverSocket;
public int num = 0;
Reactor(int port) throws IOException {
selector = Selector.open();
serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(port));
serverSocket.configureBlocking(false);
SelectionKey sk = serverSocket.register(selector,
SelectionKey.OP_ACCEPT);
sk.attach(new Acceptor());
}
public void run() { // normally in a new Thread
try {
while (!Thread.interrupted()) {
selector.select();
Set selected = selector.selectedKeys();
Iterator it = selected.iterator();
while (it.hasNext()) {
dispatch((SelectionKey) (it.next()));
}
selected.clear();
}
} catch (IOException ex) { /* ... */
}
}
void dispatch(SelectionKey k) {
Runnable r = (Runnable) (k.attachment());
if (r != null)
r.run();
}
class Acceptor implements Runnable { // inner
public void run() {
try {
num++;
SocketChannel c = serverSocket.accept();
if (c != null)
new Handler(selector, c, num);
} catch (IOException ex) { /* ... */
}
}
}
}
package snake.test.channel;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
final class Handler implements Runnable {
final SocketChannel socket;
final SelectionKey sk;
ByteBuffer input = ByteBuffer.allocate(1024);
ByteBuffer output = ByteBuffer.allocate(1024);
static final int READING = 0, SENDING = 1;
int state = READING;
private int num = 0;
Handler(Selector sel, SocketChannel c,int n) throws IOException {
System.out.println("Client Startup");
socket = c;
num = n;
c.configureBlocking(false);
// Optionally try first read now
sk = socket.register(sel, 0);
sk.attach(this);
sk.interestOps(SelectionKey.OP_READ);
sel.wakeup();
}
boolean inputIsComplete() {
return true; /* ... */
}
boolean outputIsComplete() {
return true; /* ... */
}
void process() {
//System.out.println("Sleep");
try {
Thread.sleep(100000000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// class Handler continued
public void run() {
try {
System.out.println("Run " + num);
if (state == READING)
read();
else if (state == SENDING)
send();
} catch (IOException ex) { /* ... */
}
}
void read() throws IOException {
socket.read(input);
if (inputIsComplete()) {
process();
state = SENDING;
// Normally also do first write now
sk.interestOps(SelectionKey.OP_WRITE);
}
}
void send() throws IOException {
socket.write(output);
if (outputIsComplete())
sk.cancel();
}
}
请问是否少了什么东西?
或者有什么别的技术?还是说一定使用多线程技术?
谢谢!
java socket 回调函数_请问Java网络编程如何在不使用多线程的情况下实现异步返回?...相关推荐
- java反射回调函数_用J2V8注册Java回调函数
J2V8是一套针对谷歌的V8 JavaScript引擎的Java绑定.J2V8的开发为Android平台带来了高效的Javascript的执行环境,taris.js 就是基于J2V8开发的.J2V8同 ...
- java 安卓客户端开发_《安卓网络编程》之第一篇 java环境下模拟客户端、服务器端...
1.Socket简介 在网络上的两个程序通过一个双向的通信连接实现数据的交换,这个双向链路的一端称为一个Socket.Socket通常用来实现客户方和服务方的连接.Socket是TCP/IP协议的一个 ...
- java socket接口文档_Java进阶 - 网络编程、Socket、函数式接口、常用的函数式接口...
1.网络通信协议 网络通信协议:通信协议是对计算机必须遵守的规则,只有遵守这些规则,计算机之间才能进行通信.这就好比在道路中行驶的汽车一定要遵守交通规则一样,协议中对数据的传输格式.传输速率.传输步骤 ...
- java反射的优化_请问Java反射的性能为什么比直接调用慢一个数量级左右?
Method.invoke()本身要用数组包装参数:而且每次调用都必须检查方法的可见性(在Method.invoke()里),也必须检查每个实际参数与形式参数的类型匹配性(在NativeMethodA ...
- java socket ftp登录_基于java socket的简单FTP功能实现
实现FTP的一些功能,如上传文件,下载文件,显示目录,改变目录,退出等功能 import java.io.BufferedInputStream; import java.io.BufferedOut ...
- java调用javascript函数_使用Java程序中的参数调用Javascript函数
我有Java Swing应用程序.当用户点击MenuItem时,我想使用JavaScript在HTML页面上显示图形. Java代码: if(e.getActionCommand().equals(& ...
- Java dectobin(n)函数_浙大JAVA实验题答案09answer.docx
实验9-1 Method的使用(二) 程序填空题,不要改变与输入输出有关的语句. 50010十进制转换二进制 输入一个正整数repeat (0 输入1个正整数n,将其转换为二进制后输岀. 要求定义并调 ...
- java当前时间函数_在JAVA中如何获取当前日期
一. 获取当前系统时间和日期并格式化输出: import java.util.Date; import java.text.SimpleDateFormat; public class NowStri ...
- java 调用postgresql 函数_从Java调用PostgreSQL中的存储过程
我编写了一个我想用Java调用的存储过程.但我不认为它能够对我通过的查询做任何事情.以下是我的java代码: String QUERY_LOCATION = "select (license ...
最新文章
- 《计算机网络》常考概念、英文缩写、公式大全
- Spring-基于Spring使用自定义注解及Aspect实现数据库切换
- 【新星计划】MATLAB plot绘制图像
- nvidia linux屏幕撕裂,带有Nvidia/Intel图形的Ubuntu屏幕破裂
- 如何使用事务码SMICM分析ABAP代码发起的HTTP请求的错误
- 图像处理与图像识别笔记(一)
- Pattern类与Matcher方法的验证
- pictureselector 压缩_Android 多图选择器PictureSelector 使用
- Java开发中的基本数据类型有哪些?
- I2C双向电平转换电路
- 2021-11-16-小甲鱼python教学视频总结
- v-distpicker 直辖市的修改
- ppt编辑数据链接文件不可用_excel表格编辑数据不可用-ppt插入的自带图表点击编辑数据时显示链接文件不可用...
- 塑料填充母粒行业调研报告 - 市场现状分析与发展前景预测
- 远程桌面教程及指定主机远程连接方法
- 跳过 Windows 11 的联网的方法
- 个人博客配置SSL安全文件
- 解密AI芯片的加速原理
- Oracle获取一周前,一个月前,一年前的日期
- video.js API 详解
热门文章
- android点击获得坐标,android点击MapView任意一点获得坐标
- 跨域问题是怎样造成的
- oracle+10g+cpu补丁,Oracle 10g打补丁(p5490848_10202_LINUX)
- js文件中使用jstl或者其他标签
- SpringMVC系列(十四)Spring MVC的运行流程
- 架构的坑系列:重构过程中的过度设计
- c++课程学习(未完待续)
- ASP.NET MVC的JavaScriptResult
- select - I/O多路复用
- 配置classpath,引入jar包