以下是jdk自帶的例子,我的問題見後:----------------------------------------------------------------------------------------import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.net.*;
import java.util.*;// Listen on a port for connections and write back the current time.
public class NBTimeServer
{
private static final int DEFAULT_TIME_PORT = 8900; // Constructor with no arguments creates a time server on default port.
public NBTimeServer() throws Exception
{
acceptConnections(this.DEFAULT_TIME_PORT);
} // Constructor with port argument creates a time server on specified port.
public NBTimeServer(int port) throws Exception
{
acceptConnections(port);
} // Accept connections for current time. Lazy Exception thrown.
private static void acceptConnections(int port) throws Exception
{
// Selector for incoming time requests
Selector acceptSelector = SelectorProvider.provider().openSelector(); // Create a new server socket and set to non blocking mode
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false); // Bind the server socket to the local host and port InetAddress lh = InetAddress.getLocalHost();
InetSocketAddress isa = new InetSocketAddress(lh, port);
ssc.socket().bind(isa); // Register accepts on the server socket with the selector. This
// step tells the selector that the socket wants to be put on the
// ready list when accept operations occur, so allowing multiplexed
// non-blocking I/O to take place.
SelectionKey acceptKey = ssc.register(acceptSelector, SelectionKey.OP_ACCEPT); int keysAdded = 0; // Here's where everything happens. The select method will
// return when any operations registered above have occurred, the
// thread has been interrupted, etc.
while ( (keysAdded = acceptSelector.select()) > 0)
{
// Someone is ready for I/O, get the ready keys
Set readyKeys = acceptSelector.selectedKeys();
Iterator i = readyKeys.iterator(); // Walk through the ready keys collection and process date requests.
while (i.hasNext())
{
SelectionKey sk = (SelectionKey) i.next();
i.remove();
// The key indexes into the selector so you
// can retrieve the socket that's ready for I/O
ServerSocketChannel nextReady = (ServerSocketChannel) sk.channel();
// Accept the date request and send back the date string
Socket s = nextReady.accept().socket();
// Write the current time to the socket
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
Date now = new Date();
out.println(now);
out.close();
}
}
} // Entry point.
public static void main(String[] args)
{
// Parse command line arguments and
// create a new time server (no arguments yet)
try
{
NBTimeServer nbt = new NBTimeServer();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}---------------------------------------------------------------------------------------我的理解非阻滯是在建立聯連時,可以同時建立多外連接,並且可以多個連接可以同時發送消息.但以上程序中的這段,我的理解是一次只能處理一個請求.只不過是多個請求依順序而處理了.不過,
如果第一個請求處理花了很長時間,那麽其它請求必需等待很長時間.如果前面的請求無限期等待,那麽後面的請求也無法執行. while ( (keysAdded = acceptSelector.select()) > 0)
{
// Someone is ready for I/O, get the ready keys
Set readyKeys = acceptSelector.selectedKeys();
Iterator i = readyKeys.iterator(); // Walk through the ready keys collection and process date requests.
while (i.hasNext())
{
SelectionKey sk = (SelectionKey) i.next();
i.remove();
// The key indexes into the selector so you
// can retrieve the socket that's ready for I/O
ServerSocketChannel nextReady = (ServerSocketChannel) sk.channel();
// Accept the date request and send back the date string
Socket s = nextReady.accept().socket();
// Write the current time to the socket
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
Date now = new Date();
out.println(now);
out.close();
}
}所以這段如要處理多個並發請求,還得改為多thread的. 不過如果真的是這樣,nio的非阻滯在處理多個並發請求時比傳統多thread處理好處在哪呢?
import java.nio.*;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.net.*;
import java.util.*;// Listen on a port for connections and write back the current time.
public class NBTimeServer
{
private static final int DEFAULT_TIME_PORT = 8900; // Constructor with no arguments creates a time server on default port.
public NBTimeServer() throws Exception
{
acceptConnections(this.DEFAULT_TIME_PORT);
} // Constructor with port argument creates a time server on specified port.
public NBTimeServer(int port) throws Exception
{
acceptConnections(port);
} // Accept connections for current time. Lazy Exception thrown.
private static void acceptConnections(int port) throws Exception
{
// Selector for incoming time requests
Selector acceptSelector = SelectorProvider.provider().openSelector(); // Create a new server socket and set to non blocking mode
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false); // Bind the server socket to the local host and port InetAddress lh = InetAddress.getLocalHost();
InetSocketAddress isa = new InetSocketAddress(lh, port);
ssc.socket().bind(isa); // Register accepts on the server socket with the selector. This
// step tells the selector that the socket wants to be put on the
// ready list when accept operations occur, so allowing multiplexed
// non-blocking I/O to take place.
SelectionKey acceptKey = ssc.register(acceptSelector, SelectionKey.OP_ACCEPT); int keysAdded = 0; // Here's where everything happens. The select method will
// return when any operations registered above have occurred, the
// thread has been interrupted, etc.
while ( (keysAdded = acceptSelector.select()) > 0)
{
// Someone is ready for I/O, get the ready keys
Set readyKeys = acceptSelector.selectedKeys();
Iterator i = readyKeys.iterator(); // Walk through the ready keys collection and process date requests.
while (i.hasNext())
{
SelectionKey sk = (SelectionKey) i.next();
i.remove();
// The key indexes into the selector so you
// can retrieve the socket that's ready for I/O
ServerSocketChannel nextReady = (ServerSocketChannel) sk.channel();
// Accept the date request and send back the date string
Socket s = nextReady.accept().socket();
// Write the current time to the socket
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
Date now = new Date();
out.println(now);
out.close();
}
}
} // Entry point.
public static void main(String[] args)
{
// Parse command line arguments and
// create a new time server (no arguments yet)
try
{
NBTimeServer nbt = new NBTimeServer();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}---------------------------------------------------------------------------------------我的理解非阻滯是在建立聯連時,可以同時建立多外連接,並且可以多個連接可以同時發送消息.但以上程序中的這段,我的理解是一次只能處理一個請求.只不過是多個請求依順序而處理了.不過,
如果第一個請求處理花了很長時間,那麽其它請求必需等待很長時間.如果前面的請求無限期等待,那麽後面的請求也無法執行. while ( (keysAdded = acceptSelector.select()) > 0)
{
// Someone is ready for I/O, get the ready keys
Set readyKeys = acceptSelector.selectedKeys();
Iterator i = readyKeys.iterator(); // Walk through the ready keys collection and process date requests.
while (i.hasNext())
{
SelectionKey sk = (SelectionKey) i.next();
i.remove();
// The key indexes into the selector so you
// can retrieve the socket that's ready for I/O
ServerSocketChannel nextReady = (ServerSocketChannel) sk.channel();
// Accept the date request and send back the date string
Socket s = nextReady.accept().socket();
// Write the current time to the socket
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
Date now = new Date();
out.println(now);
out.close();
}
}所以這段如要處理多個並發請求,還得改為多thread的. 不過如果真的是這樣,nio的非阻滯在處理多個並發請求時比傳統多thread處理好處在哪呢?
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货