既然说到了nio,就得谈以下几个问题
为什么会出现新io,"旧io"有什么问题吗?
ok,一步一步来,先给大家看几个例子:
我们运行Socket Test这个软件来测试一下
结果如下:
除了上面的问题,还有一个,如果我同时开两个test软件,结果会是这样:在我第一个程序敲打end之前,第二个程序发的所有消息都没有反应,但第一个程序一旦发送end,第二个程序之前发的命令会都显示出来(break与return在这样是不一样的,哪里有区别,大家自己试)
换句话说,上面的代码,只能同时运行一个客户端!
这里启用了线程的概念,都很简单,如果大家哪里还是不清楚,可以看看<<谈谈java中的线程(初级概念) >>就在我写的博客里面,很简单的一些基础知识#
显示如下
这里似乎解决了不能同时访问的问题,但是技术的进步总是这样,你解决了一个问题,马上就会出现新的三个问题
新出现的问题有
1 现在的http请求支持长连接,如果同时又10000个人在线,服务端就启动10000个线程吗? 如果是10万人呢?
2 就算不考虑第一个问题,如果多个线程涉及到对同一个文件的读写,怎么保证一致性?
3 如果我想提升某些用户的优先级,怎么办?
另外还有一个问题,在上面的例子中并没有体现出来,就是效率!我们期待一种新的io方式,来提升速度#
为什么会出现新io,"旧io"有什么问题吗?
ok,一步一步来,先给大家看几个例子:
1单线程的服务器程序
import java.net.*;
import java.io.*;
public class SocketServiceTest
{
public static void main(String[] args) throws Exception
{
ServerSocket serverSocket = new ServerSocket(10002);
Socket socket = null;
try
{
while (true)
{
socket = serverSocket.accept();
System.out.println("socket连接:" + socket.getRemoteSocketAddress().toString());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true)
{
String readLine = in.readLine();
System.out.println("收到消息" + readLine);
if("end".equals(readLine))
break;
}
}
}
catch (SocketException se)
{
System.out.println("客户端断开连接");
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
System.out.println("socket关闭:" + socket.getRemoteSocketAddress().toString());
socket.close();
}
}
}
我们运行Socket Test这个软件来测试一下
结果如下:
(为什么jfsdkof 没有显示出来? 自己想)
除了上面的问题,还有一个,如果我同时开两个test软件,结果会是这样:在我第一个程序敲打end之前,第二个程序发的所有消息都没有反应,但第一个程序一旦发送end,第二个程序之前发的命令会都显示出来(break与return在这样是不一样的,哪里有区别,大家自己试)
换句话说,上面的代码,只能同时运行一个客户端!
2多线程的服务程序
import java.net.*;
import java.io.*;
import java.util.Scanner;
public class MultithreadJIoSocketTest
{
public static void main (String[] args) throws Exception
{
ServerSocket serverSocket = new ServerSocket(10002);
Thread thread = new Thread(new Accptor(serverSocket));
thread.start();
}
}
import java.io.*;
import java.net.*;
public class Accptor implements Runnable
{
private ServerSocket serverSocket;
public Accptor(ServerSocket serverSocket)
{
this.serverSocket = serverSocket;
}
public void run()
{
while (true)
{
Socket socket = null;
try
{
socket = serverSocket.accept();
if(socket != null)
{
System.out.println("收到了socket:" + socket.getRemoteSocketAddress().toString());
Thread thread = new Thread(new Processor(socket));
thread.start();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
import java.io.*;
import java.net.*;
public class Processor implements Runnable
{
private Socket socket;
public Processor(Socket socket)
{
this.socket = socket;
}
public void run()
{
try
{
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String readLine;
while(true)
{
readLine = in.readLine();
System.out.println("收到消息" + readLine);
if("end".equals(readLine))
{
break;
}
//客户端断开连接
Thread.sleep(5000);
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (SocketException se)
{
System.out.println("客户端断开连接");
}
catch (IOException e)
{
e.printStackTrace();
}
finally {
try
{
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
这里启用了线程的概念,都很简单,如果大家哪里还是不清楚,可以看看<<谈谈java中的线程(初级概念) >>就在我写的博客里面,很简单的一些基础知识#
显示如下
这里似乎解决了不能同时访问的问题,但是技术的进步总是这样,你解决了一个问题,马上就会出现新的三个问题
新出现的问题有
1 现在的http请求支持长连接,如果同时又10000个人在线,服务端就启动10000个线程吗? 如果是10万人呢?
2 就算不考虑第一个问题,如果多个线程涉及到对同一个文件的读写,怎么保证一致性?
3 如果我想提升某些用户的优先级,怎么办?
另外还有一个问题,在上面的例子中并没有体现出来,就是效率!我们期待一种新的io方式,来提升速度#
至少上面的三个问题都说明,我们需要一种新的io方式!
OK,下一章我们再说nio