java - 具有非阻塞套接字的多线程

标签 java multithreading synchronization nio nonblocking

我正在尝试使用 nio 在 Java 中实现 TCP 服务器。 它只是使用 Selector 的 select 方法来获取准备好的键。然后处理这些 key ,如果它们是可接受的、可读的等等。服务器工作正常,直到我使用单个线程。但是当我尝试使用更多线程来处理 key 时,服务器的响应变慢并最终停止响应,比如在 4-5 个请求之后。 这就是我所做的一切:(伪)

Iterator<SelectionKey> keyIterator =  selector.selectedKeys().iterator();
while (keyIterator.hasNext()) {
                SelectionKey readyKey = keyIterator.next();
                if (readyKey.isAcceptable()) {
                    //A new connection attempt, registering socket channel with selector

                } else {
                    Worker.add( readyKey );
                }

Worker 是从 channel 执行输入/输出的线程类。 这是我的 Worker 类的代码:

private static List<SelectionKey> keyPool = Collections.synchronizedList(new LinkedList());

public static void add(SelectionKey key) {
    synchronized (keyPool) {
        keyPool.add(key);
        keyPool.notifyAll();
    }
}


public void run() {
    while ( true ) {

        SelectionKey myKey = null;
        synchronized (keyPool) {
            try {
                while (keyPool.isEmpty()) {
                    keyPool.wait();
                }
            } catch (InterruptedException ex) {                    
            }
            myKey = keyPool.remove(0);
            keyPool.notifyAll();
        }

        if (myKey != null && myKey.isValid() ) {

            if (myKey.isReadable()) {
                //Performing reading
            } else if (myKey.isWritable()) {
                //performing writing
                myKey.cancel();  
            }
        }
    }

我的基本想法是将 key 添加到 keyPool 中,各种线程可以从中获取一个 key ,一次一个。 我的 BaseServer 类本身作为线程运行。它在事件循环开始之前创建 10 个工作线程。我还尝试增加 BaseServer 线程的优先级,以便它有更多机会接受可接受的 key 。尽管如此,它在大约 8 个请求后停止响应。请帮忙,我是不是错了。提前致谢。 :)

最佳答案

第三,您没有从选定键集中删除任何内容。每次循环都必须这样做,例如通过在调用 next() 之后调用 keyIterator.remove()。

您需要阅读 NIO 教程。

关于java - 具有非阻塞套接字的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7744215/

相关文章:

multithreading - 主线程繁忙时在 Delphi 中显示启动屏幕

Mysql 数据库复制,

c# - 使用什么对象类型/实例进行同步

java - 查找字符串中模式的计数(包括重叠)

java - NoSuchMethod : Parameter comparisson differs. 相同类型,不同对象

c# - 合作/非抢占式线程避免死锁?

c++ - 什么时候调用 stringbuf::flush?

java - 用其上层变体替换正则表达式捕获

java - JLabel 未添加到 JPanel

java - 线程代码意外停止