Tag: 非阻塞

Java非阻塞IO选择器导致通道寄存器阻塞

我有两个线程,我正在处理Java NIO的非阻塞套接字。 这是线程正在做的事情: 线程1:调用选择器的select()方法的循环。 如果有任何密钥可用,则会相应地处理它们。 线程2:偶尔通过调用register()将SocketChannel注册到选择器。 问题是,除非select()的超时非常小(比如大约100ms),对register()的调用将无限期地阻塞。 即使通道配置为非阻塞,并且javadocs声明Selector对象是线程安全的(但它的选择键不是,我知道)。 所以任何人都对这个问题有什么看法? 如果我把所有东西都放在一个线程中,该应用程 那时没有问题,但我真的想要有单独的线程。 任何帮助表示赞赏。 我在下面发布了我的示例代码: 将选择(1000)更改为选择(100)并且它将起作用。 保留为select()或select(1000),但不会。 import java.io.IOException; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.Iterator; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class UDPSocket { private DatagramChannel clientChannel; private String dstHost; private int dstPort; private static Selector recvSelector; private static volatile […]

用于Java的增量流式JSON库

任何人都可以推荐一个Java的JSON库,它允许我以非阻塞的方式提供数据块吗? 我已经阅读了一个更好的Java JSON库和类似的问题,并没有找到我想要的。 基本上,我想要的是一个库,它允许我做类似以下的事情: String jsonString1 = “{ \”A broken”; String jsonString2 = ” json object\” : true }”; JSONParser p = new JSONParser(…); p.parse(jsonString1); p.isComplete(); // returns false p.parse(jsonString2); p.isComplete(); // returns true Object o = p.getResult(); 请注意,实际的键名称(“A broken json object”)在各段之间分开。 我发现的最接近的是async-json-library , 几乎完全符合我的要求,除了它无法恢复实际字符串或其他数据值在片段之间分割的对象。

中断连接sockets

我有一个GUI,其中包含要连接的服务器列表。 如果用户单击它连接到它的服务器。 如果用户单击第二个服务器,它将断开第一个服务器并连接到第二个服务器。 每个新连接都在一个新线程中运行,以便程序可以执行其他任务。 但是,如果用户在第一个服务器仍然连接时单击第二个服务器,则会有两个同时连接。 我正在使用它连接,而connect()是阻塞的行: Socket socket = new Socket(); socket.connect(socketAddress, connectTimeout); 我想也许是Thread.currentThread().interrupt(); 会工作,但没有。 我是否需要稍微重构我的代码以便继续进行第一次连接,但是之后会立即关闭它? 或者实际上是一种中断connect方法的方法。

如何避免使用Java ServerSocket阻塞?

我正在研究一个套接字监听器,它必须在2个端口上侦听2种类型的数据(端口80和端口81)。 这些数据与对数据执行的操作类型非常相似,只是因为它们到达不同的端口而不同。 我继续使用Java的ServerSocket类编写了一个实现,但后来才意识到ServerSocket类的accept()方法是块,我的实现无法承受。 所以现在我正在考虑使用Java NIO实现相同的function,但在完成了一些教程之后,我认为我比我的开始更困惑。 如果这里的某个人可以引导我完成整个过程,即使它是伪代码或技术“下一步该做什么”,那将是很棒的。 这就是我打算实现的目标。 通过调用2个类似的线程来监听,就像永远在2个端口上一样。(非阻塞)来自某个网​​络位置的远程设备连接,发送数据然后断开连接。 我想如果只知道如何使用NIO来设置服务器来监听端口,那么就可以实现localhost上的端口80,其余部分都很容易实现。 干杯

Java中的非阻塞(异步)DNS解析

是否有一种干净的方法以非阻塞的方式异步解析Java中的DNS查询(通过主机名获取IP)(即状态机,而不是1个查询= 1个线程 – 我想同时运行数万个查询,但是没有运行成千上万的线程)? 到目前为止我发现了什么: 标准InetAddress.getByName()实现是阻塞的,看起来像标准Java库缺少任何非阻塞实现。 在批量问题中解决DNS讨论了类似的问题,但找到的唯一解决方案是multithreading方法(即一个线程在每个给定时刻只处理1个查询),这不是真正可扩展的。 dnsjava库也只是阻止。 dnsjava有一些古老的非阻塞扩展,可以追溯到2006年,因此缺少任何现代Java并发内容,例如Future范例使用,以及非常有限的仅队列实现。 dnsjnio项目也是dnsjava的扩展,但它也适用于线程模型(即1个查询= 1个线程)。 asyncorg似乎是我迄今为止针对此问题找到的最佳解决方案,但是: 它也是从2007年开始,看起来已经废弃了 几乎没有任何文档/ javadoc 使用许多非标准技术,如Fun类 我错过了任何其他想法/实施? 澄清 。 我有一个相当大(每天几TB)的日志量。 每个日志行都有一个主机名,可以来自互联网上的任何地方,我需要一个IP地址作为我的进一步统计计算的主机名。 行的顺序并不重要,所以,基本上,我的想法是开始2个线程:首先迭代线: 读一行,解析它,获取主机名 发送查询到DNS服务器以解析给定的主机名,不要阻止回答 将行和DNS查询套接字句柄存储在内存中的某个缓冲区中 转到下一行 第二个线程将: 等待DNS服务器回答任何查询(使用epoll / kqueue技术) 阅读答案,找到缓冲区中的哪一行 将已解析IP的行写入输出 继续等待下一个答案 Perl中使用AnyEvent简单模型实现向我展示了我的想法通常是正确的,我可以通过这种方式轻松实现每秒15-20K查询的速度(天真的阻塞实现每秒2-3次查询 – 只是为了比较 -这就像4个数量级的差异)。 现在我需要在Java中实现相同的 – 我想跳过我自己的DNS实现;)

如何实现非阻塞IO?

在Java或C#或其他一些语言中,存在非阻塞IO设施,例如,用于套接字。 所以我可以将我的回调函数提供给非阻塞IO,一旦非阻塞IO收到任何东西,它就会调用我的回调函数。 我想知道它们是如何实施的。 如果我在场景后面创建非阻塞IO,Java或C#是否只为它们创建后台线程? 或OS底层有本机支持吗?

有没有人玩过NIO管道来过滤/拦截System.out?

正如这里建议的那样,我想在选择器循环中做到这一点。 我真正想要的是在我的选择器循环中读取写入系统的内容。 编辑1:我编写了一个完整的解决方案,只是为了找出你不能使用System.setOut重定向GC日志。 它只是直接到FD或其他东西。 显示塞子! 除非我重定向到文件并将此文件传输到我的选择器。 很多工作! 看到这里 。

如何使用带参数的exitValue()?

一篇非常好的文章(当Runtime.exec()不会)时说:你不希望你的程序阻塞等待外部进程的唯一可能的时间你将使用exitValue()而不是waitFor()可能永远不会完成 我宁愿将一个名为waitFor的布尔参数传递给exitValue()方法,以确定当前线程是否应该等待,而不是使用waitFor()方法。 布尔值会更有用,因为exitValue()是此方法的更合适的名称,并且两个方法不必在不同条件下执行相同的function。 这种简单的条件判别是输入参数的范畴。 我有完全相同的情况,我的系统调用将启动一个将继续运行的进程,直到用户决定杀死它。 如果我使用’(process.waitFor()== 0)’它将阻止程序,因为进程将无法完成。 上面文章中的作者建议exitValue()可以与’waitFor’参数一起使用。 有人尝试过吗? 任何例子都会有所帮助。 码: //启动ProcessBuilder,’str’包含一个命令 ProcessBuilder pbuilder = new ProcessBuilder(str); pbuilder.directory(new File(“/root/workspace/Project1”)); pbuilder.redirectErrorStream(true); Process prcs = pbuilder.start(); AForm.execStatustext.append(“\n=> Process is:” + prcs); // Read output StringBuilder out = new StringBuilder(); BufferedReader bfrd = new BufferedReader(new InputStreamReader(process.getInputStream())); String current_line = null, previous_line = null; while ((current_line = bfrd.readLine()) != […]

当我无缘无故地写入水槽时,NIO Pipe抛出“Broken Pipe”! 怎么调试?

我相信我已经做好了一切。 我创建一个管道,将接收器传递给写入器线程,使用OP_READ在我的选择器上注册源,启动我的选择器。 一切正常,但一旦我向水槽写东西,我就会得到一个破损的管道exception。 为什么!!! ??? 这里没有破裂的管道。 我烦了。 我如何调试/了解这里发生的事情? 有没有人有一个简单的管道示例,我可以运行来测试这是否有效。 在接收器上写入的线程和读取它的选择器。 编辑:我几乎遵循这里的建议。 在互联网上很难找到NIO管道的具体例子。 import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.Iterator; public class SystemOutPipe extends Thread { public static void main(String[] args) { try { SystemOutPipe sop = new SystemOutPipe(); sop.start(); System.out.println(“This message should be redirected to System.err\nNow waiting 5 seconds …”); Thread.sleep(5000L); sop.setStopped(true); sop.join(); } […]

线程中断没有结束阻塞调用输入流读取

我正在使用RXTX从串口读取数据。 读取是在以下列方式生成的线程内完成的: CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(port); CommPort comm = portIdentifier.open(“Whatever”, 2000); SerialPort serial = (SerialPort)comm; …settings Thread t = new Thread(new SerialReader(serial.getInputStream())); t.start(); SerialReader类实现Runnable并且无限循环,从端口读取并将数据构建到有用的包中,然后再将其发送到其他应用程序。 但是,我把它简化为以下简单: public void run() { ReadableByteChannel byteChan = Channels.newChannel(in); //in = InputStream passed to SerialReader ByteBuffer buffer = ByteBuffer.allocate(100); while (true) { try { byteChan.read(buffer); } catch (Exception e) { System.out.println(e); […]