阻塞模式体会(单线程阻塞只能干一件事)
服务器代码
public class Server {
public static void main(String[] args) throws Exception {
//创建服务器
ServerSocketChannel ssc = ServerSocketChannel.open();
//给服务器绑定端口号,以便客户端找到服务器
ssc.bind(new InetSocketAddress(8080));
//创建List集合来装多个客户端同时发来的消息
List<SocketChannel> list = new ArrayList<>();
//服务器进行工作
while (true){
System.out.println("等待连接!");
//获取客户段发来的连接
SocketChannel sc = ssc.accept();//这是阻塞模式 线程在此处停止
System.out.println("连接成功!"+sc.getRemoteAddress());
list.add(sc);
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(32);//分配缓冲区
for (SocketChannel socketChannel : list) {
System.out.println("等待客户端的数据输出!");
socketChannel.read(byteBuffer);//这是阻塞模式 线程在此处停止
byteBuffer.flip();
System.out.println(StandardCharsets.UTF_8.decode(byteBuffer).toString());
byteBuffer.clear();
}
}
}
}
客户端代码
public class Client {
public static void main(String[] args) throws Exception {
SocketChannel sc = SocketChannel.open();
sc.connect(new InetSocketAddress("localhost",8080));
System.out.println("我开始发送数据");
}
}
体会结果
客户端程序没有启动 accept()方法被阻塞,线程停止
客户端程序debug启动 没有数据输出!此时read()方法被阻塞,线程停止
客户端程序写入数据!服务器继续往下执行等待下一次的链接
但是这时客户端再次写数据,服务器没有响应。
若在这时再开启一个客户端线程连接服务器(之前的操作的有点失误,重新来了一遍端口号变了)
但是结果还是一样的,在list集合中我们保存了第一个客户端的连接,所以上此图的第二次写的内容在第二个客户端连接的时候,就会被执行。
非阻塞模式(单线程做牛做马)
服务器代码(socketChannel.configureBlocking(false))
public class Server {
public static void main(String[] args) throws Exception {
//创建服务器
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);//设置非阻塞
//给服务器绑定端口号,以便客户端找到服务器
ssc.bind(new InetSocketAddress(8080));
//创建List集合来装多个客户端同时发来的消息
List<SocketChannel> list = new ArrayList<>();
//服务器进行工作
while (true){
Thread.sleep(1000);
System.out.println("等待连接!");
//获取客户段发来的连接
SocketChannel sc = ssc.accept();//这是非阻塞模式 返回值null;继续往下执行
if (sc != null){
sc.configureBlocking(false);
System.out.println("连接成功!"+sc.getRemoteAddress());
list.add(sc);
Thread.sleep(1000);
}
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(32);//分配缓冲区
for (SocketChannel socketChannel : list) {
System.out.println("等待客户端的数据输出!");
socketChannel.read(byteBuffer);//这是非阻塞模式 返回值0
byteBuffer.flip();
System.out.println(StandardCharsets.UTF_8.decode(byteBuffer).toString());
byteBuffer.clear();
}
}
}
}