java NIO多线程优化

package com.dronff.one;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * @author tyf
 * 2022/5/15
 */
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(9888));
        Selector selector = Selector.open();
        serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
        WorkSelector workSelector = new WorkSelector("work-01");
        while (selector.select()>0){
            System.out.println("一轮");
            Iterator<SelectionKey> selectionKeys = selector.selectedKeys().iterator();
            while(selectionKeys.hasNext()){
                System.out.println("进入");
                SelectionKey selectionKey = selectionKeys.next();
                if(selectionKey.isAcceptable()){
                    //为accept就绪状态
                    //获取SocketChannel对象
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    socketChannel.configureBlocking(false);
                    workSelector.registry(socketChannel);
                }
                selectionKeys.remove();
            }
        }
    }
    static class WorkSelector implements Runnable{
        //是否被初始化过
        boolean started = false;
        String name;
        Selector selector;
        ConcurrentLinkedQueue<Runnable> queue = new ConcurrentLinkedQueue<>();
        Thread thread;
        public WorkSelector(String name){
            this.name = name;
        }
        public void registry(SocketChannel socketChannel) throws IOException {
            if(!this.started){
                //还没初始化过
                //初始化selector
                this.selector = Selector.open();
                //创建新线程
                System.out.println("开始创建新线程");
                this.thread = new Thread(this,this.name);
                this.thread.start();
                System.out.println("创建新线程完成");
            }
            System.out.println("添加任务中");
            this.queue.add(()->{
                try {
                    socketChannel.register(selector,SelectionKey.OP_READ);
                } catch (ClosedChannelException e) {
                    e.printStackTrace();
                }
            });
            System.out.println("添加任务成功");
            selector.wakeup();
        }

        @Override
        public void run() {
            try {
                while (true){
                    //让worker子线程阻塞在这里,直到主线程调用wakeup方法唤醒它
                    this.selector.select();
                    Iterator<SelectionKey> selectionKeys = this.selector.keys().iterator();
                    Runnable task = queue.poll();
                    if(task != null){
                        task.run();
                    }
                    while (selectionKeys.hasNext()){
                        SelectionKey selectionKey = selectionKeys.next();
                        if(selectionKey.isReadable()){
                            SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                            System.out.print("收到信息:");
                            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                            int len = socketChannel.read(byteBuffer);
                            System.out.println(new String(byteBuffer.array(),0,len));
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }


        }
    }
}

 

posted @ 2022-05-19 22:01  dronff  阅读(89)  评论(0)    收藏  举报