java的BIO实现

BIO(同步阻塞式IO)

在JDK1.4之前,用Java编写网络请求,都是建立一个ServerSocket,然后,客户端建立Socket时就会询问是否有线程可以处理,如果没有,要么等待,要么被拒绝。即:一个连接,要求Server对应一个处理线程。

单线程处理

package one;

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

/**
 * BIO服务端
 */
public class BioService1 {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(10101);
        System.out.println("服务器启动!");
        while (true){
            //获取一个套接字(阻塞)
            final Socket socket = serverSocket.accept();
            System.out.println("来了一个新客户端!");
            //业务处理
            handler(socket);
        }
    }

    /**
     * 读取数据
     * @param socket
     */
    private static void handler(Socket socket){
        try{
            byte[] bytes = new byte[1024];
            InputStream inputStream = socket.getInputStream();
            while (true){
                //读取数据 阻塞
                int read = inputStream.read(bytes);
                if(read != -1){
                    System.out.println(new String(bytes,0,read));
                }else{
                    break;
                }
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }finally {
            try{
                System.out.println("socket关闭");
                socket.close();
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
    }
}
本实例是一个简单的BIO的实现,在这里需要说明几个点阻塞点,一个是获取相应的套接字时,一个是读取数据时,通过运行该程序,使用telnet工具可以证实。

        上面的demo中存在的问题,运行该demo,通过telnet测试可知,该服务端一次只能接收一个客户端的请求,即:服务端接收了一个客户端请求后,服务端阻塞在读数据上时,此时,有另一个客户端请求链接该服务端,服务器端是无法接收该链接的,因为,服务器端只有一个线程,而该线程现已经被阻塞了。要想让服务器端实现同时处理多个客户端的请求,可以通过多线程进行解决。

多线程的处理



import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 采用多线程的方式进行处理
 */
public class BioService2 {
    public static void main(String[] args) throws IOException {
        ExecutorService newCashedThreadPool = Executors.newCachedThreadPool();
        ServerSocket serverSocket = new ServerSocket(10101);
        System.out.println("服务器启动!");
        while (true){
            //获取一个套接字(阻塞)
            final Socket socket = serverSocket.accept();
            System.out.println("来了一个新客户端!");
            newCashedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    //业务处理
                    handler(socket);
                }
            });
        }
    }

    /**
     * 读取数据
     * @param socket
     */
    private static void handler(Socket socket){
        try{
            byte[] bytes = new byte[1024];
            InputStream inputStream = socket.getInputStream();
            while (true){
                //读取数据 阻塞
                int read = inputStream.read(bytes);
                if(read != -1){
                    System.out.println(new String(bytes,0,read));
                }else{
                    break;
                }
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }finally {
            try{
                System.out.println("socket关闭");
                socket.close();
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
    }
}
该服务器端每次接收到一个客户端链接时,就会创建一个线程进行业务处理,即:每个链接都会有单独的一个线程进行为它服务。这种方式是非常消耗资源的,这种方式要求的链接都是短连接,通过这种要求,来使每个链接占用的线程的时间缩减到最小,从而可以进行更多的链接处理。


总结

        单线程的服务器端,每次只能处理一个客户端请求;多线程的服务器端,将接收客户端链接和业务分开,将业务处理使用多线程,从而达到可以处理多个客户单请求,即:一个客户端一个线程,这种方式非常的消耗资源。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值