Netty入门--伪异步I/O

同步阻塞I/O也就是一个客户端请求,服务端需要开启一个线程处理,无法满足高并发需求。后来前辈对这种线程模型进行了优化--服务端通过一个线程池来处理多个客户端的请求接入,形成客户端个数M:线程池最大线程数N的比例关系,其中M可以远远大于N。通过线程池客户灵活地调配线程资源,设置线程的最大值,防止由于海量并发接入导致线程耗尽。

采用线程池和任务队列可以实现一种伪异步的I/O通信模型

下面通过一个例子来演示

package com.hueason.netty.n1.tpio;


import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by Administrator on 2017/4/18.
 */
public class TimeServer {
    public static void main(String[] args) throws IOException {
        int port = 8080;
        if (args != null && args.length > 0) {
            port = Integer.valueOf(args[0]);
        }
        ServerSocket server = null;
        try {
            server = new ServerSocket(port);
            System.out.println("The time server is start in port :" + port);
            Socket socket = null;
            //创建I/O任务线程池
            TimeServerHandlerExecutePool singleExecutor = new TimeServerHandlerExecutePool(50, 10000);
            while (true) {
                socket = server.accept();
                singleExecutor.execute(new TimeServerHandler(socket));
            }

        }finally {
            if(server != null){
                System.out.println("The time server close");
                server.close();
                server = null;
            }
        }

    }
}
 


package com.hueason.netty.n1.tpio;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2017/4/18.
 */
public class TimeServerHandlerExecutePool {

    private ExecutorService executor;

    public TimeServerHandlerExecutePool(int maxPoolSize, int queueSize) {
        executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),maxPoolSize,120L, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(queueSize));
    }

    public void execute(Runnable task) {
        executor.execute(task);
    }
}

客户端

package com.hueason.netty.n1.tpio;


import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by Administrator on 2017/4/18.
 */
public class TimeServer {
    public static void main(String[] args) throws IOException {
        int port = 8080;
        if (args != null && args.length > 0) {
            port = Integer.valueOf(args[0]);
        }
        ServerSocket server = null;
        try {
            server = new ServerSocket(port);
            System.out.println("The time server is start in port :" + port);
            Socket socket = null;
            //创建I/O任务线程池
            TimeServerHandlerExecutePool singleExecutor = new TimeServerHandlerExecutePool(50, 10000);
            while (true) {
                socket = server.accept();
                singleExecutor.execute(new TimeServerHandler(socket));
            }

        }finally {
            if(server != null){
                System.out.println("The time server close");
                server.close();
                server = null;
            }
        }

    }
}


如Server中所示,当新的客户端接入时,将客户端的Socket封装成一个Taskt投递到线程池中进行处理,此处使用的是JDK自带的线程池,线程池维护这一个消息队列和N个活跃线程,对消息队列总的任务进行处理。

伪异步的优势:由于线程池客户设置消息队列的大小和最大线程数,因此,它的资源占用是可控的,无论多少个客户端并发访问,都不会导致资源的耗尽和宕机。

弊端:底层Socket的读和写操作都还是同步阻塞的,阻塞的时间取决于客户端I/O线程的处理速度和网络I/O的传输速度。由于在生产环境中这两项都无法绝对保证,所以系统的可靠性不高。

伪异步I/O仅仅是对BIO线程模型的一个简单优化,无法从根本上解决同步I/O导致的通信线程阻塞问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值