更新時(shí)間:2023-03-22 來源:黑馬程序員 瀏覽量:
IT就到黑馬程序員.gif)
BIO、NIO、AIO 都是 Java 中用于實(shí)現(xiàn)網(wǎng)絡(luò)編程的三種不同的方式,它們有以下區(qū)別:
1.BIO (Blocking I/O):傳統(tǒng)的阻塞式 I/O,每個(gè)連接都需要一個(gè)線程來處理,當(dāng)連接數(shù)較多時(shí),會(huì)導(dǎo)致系統(tǒng)資源消耗嚴(yán)重,性能較差。
2.NIO (Non-blocking I/O):非阻塞式 I/O,通過使用單線程輪詢多個(gè)連接的方式來實(shí)現(xiàn)高效的處理方式,可以支持較大數(shù)量的并發(fā)連接,但編程模型較為復(fù)雜。
3.AIO (Asynchronous I/O):異步 I/O,通過回調(diào)方式實(shí)現(xiàn)高效的 I/O 操作,可以大大降低系統(tǒng)資源的消耗,適用于高并發(fā)、高吞吐量的場(chǎng)景,但在實(shí)際使用中可能會(huì)受到操作系統(tǒng)和硬件的限制。
下面是 Java 中分別使用 BIO、NIO、AIO 實(shí)現(xiàn)簡單的網(wǎng)絡(luò)通信的示例代碼:
BIO 示例代碼:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class BioServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
Socket socket = serverSocket.accept();
new Thread(() -> {
try {
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
} NIO 示例代碼:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class NioServer {
private Selector selector;
public static void main(String[] args) throws IOException {
new NioServer().startServer();
}
public void startServer() throws IOException {
selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress("localhost", 8000));
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Server started on port 8000...");
while (true) {
selector.select();
Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if (key.isAcceptable()) {
acceptConnection(key);
} else if (key.isReadable()) {
readFromClient(key);
}
keyIterator.remove();
}
}
}
private void acceptConnection(SelectionKey key) throws IOException {
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel socketChannel = serverChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
System.out.println("Connection accepted from client: " + socketChannel.getRemoteAddress());
}
private void readFromClient(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = socketChannel.read(buffer);
if (bytesRead == -1) {
socketChannel.close();
System.out.println("Connection closed by client: " + socketChannel.getRemoteAddress());
} else {
byte[] data = new byte[bytesRead];
buffer.flip();
buffer.get(data, 0, bytesRead);
System.out.println("Received message from client: " + new String(data));
socketChannel.write(ByteBuffer.wrap("Hello from server".getBytes()));
}
}
} AIO 示例代碼:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class AioServer {
public static void main(String[] args) throws IOException {
AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(8080));
serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
@Override
public void completed(AsynchronousSocketChannel result, Object attachment) {
serverSocketChannel.accept(null, this);
ByteBuffer buffer = ByteBuffer.allocate(1024);
result.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer buffer) {
if (result > 0) {
buffer.flip();
byte[] bytes = new byte[buffer.limit()];
buffer.get(bytes);
System.out.println(new String(bytes));
buffer.clear();
result.write(ByteBuffer.wrap("Hello, client!".getBytes()));
} else if (result == -1) {
try {
result.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
try {
result.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
@Override
public void failed(Throwable exc, Object attachment) {
exc.printStackTrace();
}
});
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}這些代碼僅作為簡單的演示,實(shí)際應(yīng)用中需要考慮更多的細(xì)節(jié)和異常處理。
1024首播|39歲程序員逆襲記:不被年齡定義,AI浪潮里再迎春天
2025-10-241024程序員節(jié)丨10年同行,致敬用代碼改變世界的你
2025-10-24【AI設(shè)計(jì)】北京143期畢業(yè)僅36天,全員拿下高薪offer!黑馬AI設(shè)計(jì)連續(xù)6期100%高薪就業(yè)
2025-09-19【跨境電商運(yùn)營】深圳跨境電商運(yùn)營畢業(yè)22個(gè)工作日,就業(yè)率91%+,最高薪資達(dá)13500元
2025-09-19【AI運(yùn)維】鄭州運(yùn)維1期就業(yè)班,畢業(yè)14個(gè)工作日,班級(jí)93%同學(xué)已拿到Offer, 一線均薪資 1W+
2025-09-19【AI鴻蒙開發(fā)】上海校區(qū)AI鴻蒙開發(fā)4期5期,距離畢業(yè)21天,就業(yè)率91%,平均薪資14046元
2025-09-19