您的位置:首页 > 理论基础 > 计算机网络

java aio 网络编程 服务端

2016-08-30 22:55 218 查看

    今天测试了一下AsynchronousServerSocketChannel进行网络编程,发现这个效率确实高。讲一下测试场景,AsynchronousServerSocketChannel监听连接,获取到连接以后,提交给线程池去执行任务。一开始有些地方比较迷惑,比如启动一个5个线程的连接池,当我有10个连接进来,按照每一个连接都会封装成任务的做法,岂不是有五个一开始会等待,直到之前的五个中有任务执行完了,剩余的五个任务才会陆续执行,这样的话,为什么人们都说它效率高呢?

    反正我一开始是有这个想法,于是我写了个测试,验证我的想法,发现并不是我想的那样,先看看代码,然后再详细说明一下。

 

package com.pzn.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class AioServer {

public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
//
ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);

//
AsynchronousServerSocketChannel boss = AsynchronousServerSocketChannel.open();
boss.bind(new InetSocketAddress("127.0.0.1", 9000));

while (true) {

System.out.println("active thread... " + pool.getActiveCount());

AsynchronousSocketChannel worker = boss.accept().get();
System.out.println("accepted a new connect.");
pool.submit(new Task(worker));
}

}

}

   

package com.pzn.aio;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.TimeUnit;

public class Task implements Runnable {

private final AsynchronousSocketChannel worker;

public Task(AsynchronousSocketChannel worker) {
this.worker = worker;
}

public void run() {
try {
worker.write(ByteBuffer.wrap("i am server.".getBytes("utf-8")), null, new CompletionHandler<Integer, Object>() {
public void completed(Integer result, Object attachment) {
try {
TimeUnit.SECONDS.sleep(5);
System.out.println("write completed.");
worker.close();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void failed(Throwable exc, Object attachment) {
System.out.println("write failed.");
}
});
System.out.println(Thread.currentThread() + " execute Asynchronous task.");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}

}

    Task这个任务中,调用AsynchronousSocketChannel的write方法使用异步的方式,最后一个参数是回调,当server写数据完成后,会执行回调中的方法,我在回调方法completed中睡眠5秒时为了观察效果,看看线程池是否可以超过5个任务同时连接。

 

    结果表明,是可以的。实际上这个Task的run方法会立即执行完,根本不会去管回调中的睡眠时间,这样就相当于线程池会马上有空闲线程来处理新的连接,当然还是有一点的延迟,但不至于延迟等待5秒。特别要注意的是:执行回掉的方法,这个就不是我们所能干预的了,依赖操作系统的机制来进入回调,回调方法的执行已经和线程池没有关系了,因为所有提交的Task的run方法都已经执行结束了。

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐