我指的是在不使用多线程的情况下进行并发处理

具体的情况是,在不使用多线程的情况下,服务器侦听某个端口,在有连接进来的时候会调用某个函数对此连接进行处理,但是由于处理的过程可能会比较长,为了不让后面连接的用户等待,需要此函数能异步返回,而不是阻塞在这个函数。

之所以希望不使用多线程,是因为考虑到同时连接的用户数会比较多,如果用多线程的话,线程创建,销毁和切换的开销会太大。虽然可以使用线程池,但是这样只是省去了创建和销毁线程的开销,线程切换的开销还是会存在,而且线程的数目也不好确定。

.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网络编程如何在不使用多线程的情况下实现异步返回?...相关推荐

  1. java反射回调函数_用J2V8注册Java回调函数

    J2V8是一套针对谷歌的V8 JavaScript引擎的Java绑定.J2V8的开发为Android平台带来了高效的Javascript的执行环境,taris.js 就是基于J2V8开发的.J2V8同 ...

  2. java 安卓客户端开发_《安卓网络编程》之第一篇 java环境下模拟客户端、服务器端...

    1.Socket简介 在网络上的两个程序通过一个双向的通信连接实现数据的交换,这个双向链路的一端称为一个Socket.Socket通常用来实现客户方和服务方的连接.Socket是TCP/IP协议的一个 ...

  3. java socket接口文档_Java进阶 - 网络编程、Socket、函数式接口、常用的函数式接口...

    1.网络通信协议 网络通信协议:通信协议是对计算机必须遵守的规则,只有遵守这些规则,计算机之间才能进行通信.这就好比在道路中行驶的汽车一定要遵守交通规则一样,协议中对数据的传输格式.传输速率.传输步骤 ...

  4. java反射的优化_请问Java反射的性能为什么比直接调用慢一个数量级左右?

    Method.invoke()本身要用数组包装参数:而且每次调用都必须检查方法的可见性(在Method.invoke()里),也必须检查每个实际参数与形式参数的类型匹配性(在NativeMethodA ...

  5. java socket ftp登录_基于java socket的简单FTP功能实现

    实现FTP的一些功能,如上传文件,下载文件,显示目录,改变目录,退出等功能 import java.io.BufferedInputStream; import java.io.BufferedOut ...

  6. java调用javascript函数_使用Java程序中的参数调用Javascript函数

    我有Java Swing应用程序.当用户点击MenuItem时,我想使用JavaScript在HTML页面上显示图形. Java代码: if(e.getActionCommand().equals(& ...

  7. Java dectobin(n)函数_浙大JAVA实验题答案09answer.docx

    实验9-1 Method的使用(二) 程序填空题,不要改变与输入输出有关的语句. 50010十进制转换二进制 输入一个正整数repeat (0 输入1个正整数n,将其转换为二进制后输岀. 要求定义并调 ...

  8. java当前时间函数_在JAVA中如何获取当前日期

    一. 获取当前系统时间和日期并格式化输出: import java.util.Date; import java.text.SimpleDateFormat; public class NowStri ...

  9. java 调用postgresql 函数_从Java调用PostgreSQL中的存储过程

    我编写了一个我想用Java调用的存储过程.但我不认为它能够对我通过的查询做任何事情.以下是我的java代码: String QUERY_LOCATION = "select (license ...

最新文章

  1. 《计算机网络》常考概念、英文缩写、公式大全
  2. Spring-基于Spring使用自定义注解及Aspect实现数据库切换
  3. 【新星计划】MATLAB plot绘制图像
  4. nvidia linux屏幕撕裂,带有Nvidia/Intel图形的Ubuntu屏幕破裂
  5. 如何使用事务码SMICM分析ABAP代码发起的HTTP请求的错误
  6. 图像处理与图像识别笔记(一)
  7. Pattern类与Matcher方法的验证
  8. pictureselector 压缩_Android 多图选择器PictureSelector 使用
  9. Java开发中的基本数据类型有哪些?
  10. I2C双向电平转换电路
  11. 2021-11-16-小甲鱼python教学视频总结
  12. v-distpicker 直辖市的修改
  13. ppt编辑数据链接文件不可用_excel表格编辑数据不可用-ppt插入的自带图表点击编辑数据时显示链接文件不可用...
  14. 塑料填充母粒行业调研报告 - 市场现状分析与发展前景预测
  15. 远程桌面教程及指定主机远程连接方法
  16. 跳过 Windows 11 的联网的方法
  17. 个人博客配置SSL安全文件
  18. 解密AI芯片的加速原理
  19. Oracle获取一周前,一个月前,一年前的日期
  20. video.js API 详解

热门文章

  1. android点击获得坐标,android点击MapView任意一点获得坐标
  2. 跨域问题是怎样造成的
  3. oracle+10g+cpu补丁,Oracle 10g打补丁(p5490848_10202_LINUX)
  4. js文件中使用jstl或者其他标签
  5. SpringMVC系列(十四)Spring MVC的运行流程
  6. 架构的坑系列:重构过程中的过度设计
  7. c++课程学习(未完待续)
  8. ASP.NET MVC的JavaScriptResult
  9. select - I/O多路复用
  10. 配置classpath,引入jar包