傳統BIO的缺點:
- 在accept的時候會作出放棄CPU的操作 線程阻塞
- 在socket.getInputStream.read();的時候會造成線程阻塞
- BIO想實現併發需要採用多線程的方式 但是多線程有很多缺點(最大的缺點:消耗程序資源)
傳統BIO服務器NetServer.class代碼
public class NetServer {
static byte []bytes=new byte[1024];
public static void main(String[] args) {
try {
ServerSocket serverSocket=new ServerSocket(9098);
while (true) {
System.out.println("accept wait coon");
Socket socket = serverSocket.accept();
System.out.println("conn success");
System.out.println("read wait conn");
//放棄CPU
int read = socket.getInputStream().read(bytes);
System.out.println(read+"========這是read的長度");
System.out.println("data success");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
傳統BIO客戶端NetClient.class代碼
public class NetClient {
public static void main(String[] args) {
try {
Socket socket=new Socket("127.0.0.1",9098);
Scanner scanner=new Scanner(System.in);
String next = scanner.next();
socket.getOutputStream().write(next.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
NIO的設計理念: 使用單線程實現高併發
針對傳統BIO的缺點,sun公司推出了NIO
Nio Demo
package crawler.Socket;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName NioTemp
* @Description TODO
* @Author XuWenXiao
* @Date 2020/5/15 9:47
* @Version 1.0
**/
public class NioTemp {
static ByteBuffer byteBuffer=ByteBuffer.allocate(512);
static List<SocketChannel> socketChannels=new ArrayList<SocketChannel>();
public static void main(String[] args) {
try {
ServerSocketChannel serverSocket=ServerSocketChannel.open();
SocketAddress socketAddress=new InetSocketAddress("127.0.0.1",9098);
serverSocket.bind(socketAddress);
//設置accept爲非阻塞
serverSocket.configureBlocking(false);
while (true){
for (SocketChannel socketChannel : socketChannels) {
int read=socketChannel.read(byteBuffer);
if (read>0){
System.out.println(read+"讀取到數據的長度 read ");
byteBuffer.flip();
byte[]bytes=new byte[read];
byteBuffer.get(bytes);
String s=new String(bytes);
System.out.println(s);
byteBuffer.flip();
}
}
SocketChannel accept=serverSocket.accept();
if (accept!=null){
System.out.println("conn success");
//設置read 操作爲非阻塞
accept.configureBlocking(false);
socketChannels.add(accept);
System.out.println(socketChannels.size()+"打印集合的長度 socketChannels.size()");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}