一、 java.util.concurrent
线程池: ExecutorService pool = Executors.newFixedThreadPool(poolSize);
用工具类Executors产生线程池(ThreadPoolExecutor),线程池大小poolSize
将线程加入到线程池: pool.execute(new Handler(serverSocket.accept()));
同步集合:CopyOnWriteArrayList<E> 当遍历操作的数量大大超过可变操作的数量时使用。
原子操作:AtomicInteger 可以用原子方式更新的 int
值
二、java.nio
服务器端
public class MyNioServer extends Thread{
private Selector selector;
private ServerSocketChannel ssChannel;
private ByteBuffer bbf;
public static void main(String[] args) {
new MyNioServer().start();
}
public MyNioServer(){
try {
selector = Selector.open();//选择器
ssChannel = ServerSocketChannel.open();//服务器端通道
ServerSocket ss = ssChannel.socket();//通道的socket
ss.bind(new InetSocketAddress(3333));//设置监听端口
ssChannel.configureBlocking(false);//设置为非阻塞
ssChannel.register(selector,SelectionKey.OP_ACCEPT);//注册有选择器监听
bbf = ByteBuffer.allocate(100);
System.out.println("======服务器启动======");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
do {
try {
selector.select();
// System.out.println("======选择器启动======");
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator it = selectedKeys.iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
it.remove();
dealSelectionKey(key);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} while (true);
}
public void dealSelectionKey(SelectionKey key){
System.out.println("========处理请求=======");
if(key.isAcceptable()){
try {
System.out.println("=======链接=======");
ServerSocketChannel ssChannel = (ServerSocketChannel)key.channel(); //拿到注册过的sschannel
SocketChannel sChannel = ssChannel.accept(); //接受的schannel
sChannel.configureBlocking(false); //设置成非阻塞
sChannel.register(this.selector, SelectionKey.OP_READ); //注册schannel
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else if(key.isReadable()){
System.out.println("=======读取=======");
SocketChannel sChannel = (SocketChannel)key.channel();
try {
int count = sChannel.read(bbf);
if(count>0){//读到了数据
byte[] bs = bbf.array();
System.out.println(count+"----"+new String(bs));
key.interestOps(SelectionKey.OP_WRITE);
}else{
System.out.println("===================channel is close================");
sChannel.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bbf.clear();
System.out.println("服务器端读取完成");
}else if(key.isValid() && key.isWritable()){
System.out.println("=======写出=======");
try {
SocketChannel channel = (SocketChannel) key.channel();
channel.write(ByteBuffer.wrap(new byte[]{'h'}));
key.interestOps(SelectionKey.OP_READ);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("服务器端写出完成");
}
}
}
客服端(socket):
Socket socket = new Socket("192.168.102.5",3333);
String msg = new String("hello nio");
socket.getOutputStream().write(msg.getBytes());
socket.getOutputStream().flush();
System.out.println(socket.getInputStream().read());;
Thread.sleep(5000);
socket.getOutputStream().write(new byte[]{'q'});
socket.getOutputStream().flush();
Thread.sleep(1000); //一定要sleep一会
socket.close();
如果没有sleep:
java.io.IOException: An established connection was aborted by the software in your host machine