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();

}

}

请问是否少了什么东西?

或者有什么别的技术?还是说一定使用多线程技术?

谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值