Tag: nio

ThreadLocal是否可以安全地与Tomcat NIO Connector一起使用

在负载测试期间测试Tomcat NIO连接器时,我们想到了这一点。 我使用ThreadLocal另外我使用Spring,我知道在几个地方它也使用它。 由于NIO连接器每个连接没有一个线程,我担心如果ThreadLocal对象在清理之前与另一个线程共享,则可能导致很难找到错误。 但是,我认为这不是一个问题,因为它不是我能找到的文件警告,也没有发现任何其他post警告这一点。 我假设NIO连接器对服务于实际请求的线程没有影响。 在我采用这个假设之前,我希望找到一些具体的证据。

NIO选择器:如何在选择时正确注册新通道

我有一个带有私有Selector的子类Thread和一个公共register(SelectableChannel channel, …)方法,它允许其他线程将通道注册到选择器。 如上所述,通道的register()在选择器的select() / select(long timeout)期间阻塞,因此我们需要wakeup()选择器。 我的线程无限期地选择(除非它被中断)并且它实际上设法在调用通道的register()之前进入下一个选择。 所以我认为我使用带有synchronized块的简单锁来确保register()首先发生。 代码:(为了便于阅读,删除了不相关的代码) public class SelectorThread extends Thread { … public void register(SelectableChannel channel, Attachment attachment) throws IOException { channel.configureBlocking(false); synchronized (this) { // LOCKING OCCURS HERE selector.wakeup(); channel.register(selector, SelectionKey.OP_READ, attachment); } } @Override public void run() { int ready; Set readyKeys; while (!isInterrupted()) { synchronized (this) {} […]

如何从java.nio.Path获取路径字符串?

用更多信息重写了问题 我有一些使用相对路径创建Path对象的代码,如: Paths.get(“..”, “folder”).resolve(“filename”) 。 后来,我想从它获取路径字符串“.. \ folder \ filename”(我在Windows上,所以反斜杠)。 当我使用手动编译或从Eclipse运行此代码时,这很好。 但是,当我使用Maven运行它时,它不再起作用了。 toString()方法返回[.., folder, filename]而不是实际的路径字符串。 使用path.normalize()没有帮助。 使用path.toFile().getPath()会返回我正在寻找的东西,但我觉得应该有一个只使用nio.path API的解决方案。

使文件传输更高效Java

我有两台无线电脑连接到N无线路由器。 这些PC中的每一台都以108-150Mbps的速度连接。 从理论上讲,我应该能够在绝对最佳条件下以13.5MB / s的速度传输到18.75MB / s。 第一台计算机(即发送)使用非常快的SSD,如果我没记错的话,大约100MB / s。 CPU使用率也低于20%。 它在656367ms发送了1960273535字节(1.8GB)。 那是2.8MB / s(108兆比特中的22个)。 当我打开任务管理器时,我发现只有25-27%的网络连接被使用。 我正在寻找可以使传输更快(通过网络)的任何想法,建议或改进。 我在考虑从线程上的磁盘缓冲文件并从另一个线程发送缓冲的数据,但我不确定这是不是一个好主意。 这是SSCCE: 主办: import java.io.*; import java.net.*; public class Host { public static void main(String[] args) throws IOException { ServerSocket servsock = new ServerSocket(15064); Socket sock = servsock.accept(); long time = System.currentTimeMillis(); OutputStream out = sock.getOutputStream(); FileInputStream fileInputStream […]

Java NIO Pipe vs BlockingQueue

我刚刚发现它只有一个NIO工具,Java NIO Pipe,用于在线程之间传递数据。 使用此机制是否优于通过队列传递的更传统的消息,例如ArrayBlockingQueue?

Java:通过Object(In | Out)putStreams阻塞SocketChannel上是否可以进行并发读写?

我在阻塞的SocketChannel上创建了一个ObjectInputSteam和ObjectOutputStream ,并尝试同时读写。 我的代码是这样的: socketChannel = SocketChannel.open(destNode); objectOutputStream = new ObjectOutputStream(Channels.newOutputStream(socketChannel)); objectInputStream = new ObjectInputStream(Channels.newInputStream(socketChannel)); Thread replyThread = new Thread(“SendRunnable-ReplyThread”) { @Override public void run() { try { byte reply = objectInputStream.readByte();//(A) //..process reply } catch (Throwable e) { logger.warn(“Problem reading receive reply.”, e); } } }; replyThread.start(); objectOutputStream.writeObject(someObject);//(B) //..more writing 问题是在行(B)块处写入,直到在行(A)处的读取完成(由SelectableChannel#blockingLock()返回的对象上的块)。 但app逻辑规定在完成所有写操作之前读取不会完成,因此我们有一个有效的死锁。 SocketChannel javadocs表示支持并发读写。 当我尝试使用常规Socket解决方案时,我没有遇到过这样的问题: […]

如何使用NIO将InputStream写入File?

我使用以下方式将InputStream写入File : private void writeToFile(InputStream stream) throws IOException { String filePath = “C:\\Test.jpg”; FileChannel outChannel = new FileOutputStream(filePath).getChannel(); ReadableByteChannel inChannel = Channels.newChannel(stream); ByteBuffer buffer = ByteBuffer.allocate(1024); while(true) { if(inChannel.read(buffer) == -1) { break; } buffer.flip(); outChannel.write(buffer); buffer.clear(); } inChannel.close(); outChannel.close(); } 我想知道这是否是使用NIO的正确方法。 我读过一个方法FileChannel.transferFrom ,它有三个参数: ReadableByteChannel src 多头头寸 长计数 在我的情况下,我只有src ,我没有position和count ,有什么方法可以使用此方法来创建文件? 另外对于Image,还有更好的方法只能从InputStream和NIO创建图像吗? 任何信息对我都非常有用。 这里有类似的问题,在SO中,但我找不到适合我的案例的特定解决方案。

Java NIO select()返回没有选中的键 – 为什么?

在编写一些测试代码时,我发现Selector.select()可以在没有Selector.selectedKeys()的情况下返回,其中包含要处理的任何键。 当我注册一个accept()ed频道时,会发生这种情况 SelectionKey.OP_READ | SelectionKey.OP_CONNECT 作为感兴趣的业务。 根据文档,select()应该在以下时间返回: 1)有可以采取行动的渠道。 2)您明确调用Selector.wakeup() – 未选择任何键。 3)显式Thread.interrupt()执行select()的线程 – 没有选择键。 如果我在select()之后没有键,我必须在case(2)和(3)中。 但是,我的代码不是调用wakeup()或interrupt()来启动这些返回。 关于是什么导致这种行为的任何想法?

java.nio选择器和SocketChannel用于继续流式传输

我目前正在为一个应用程序使用java.nio.channel.Selectors和SocketChannels,该应用程序将打开1对多连接以继续流式传输到服务器。 我的应用程序有三个线程:StreamWriteWorker – 对SocketChannel执行写操作,StreamReadWorker – 从缓冲区读取字节并解析内容,StreamTaskDispatcher – 执行Selector对readyOps的选择,并为工作线程调度新的runnable。 问题 – 选择器的选择方法上的调用仅在第一次调用时返回值> 0(有效的readyOps); 我能够在所有就绪通道上执行一次写入和发送数据,但是Selector选择方法的以下所有调用都返回0。 问题:每次读/写后我是否需要在SocketChannel上调用close(我希望不是!)? 如果不是什么原因可能导致SocketChannel无法用于任何读/写操作? 对不起,我不能发布代码,但我希望我已经清楚地解释了问题,以便有人帮忙。 我已经搜索了答案,我看到你关闭后不能重用SocketChannel连接,但是我的频道不应该关闭,服务器永远不会收到EOF流结果。 我取得了一些进展,并发现由于json解析错误,服务器应用程序上没有发生写操作。 所以现在我的客户端应用程序代码上的SocketChannel在处理读取操作后就可以进行另一次写操作了。 我想这是SocketChannels的TCP特性。 但是,SocketChannel不可用于服务器应用程序端的另一个读取操作。 这是SocketChannels的正常行为吗? 在读取操作之后是否需要在客户端关闭连接并建立新连接? 这是我想要做的代码示例: package org.stream.socket; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CodingErrorAction; import java.util.HashMap; import java.util.Iterator; import […]

每个UDP数据报的Netty不同管道

我们已经有一个已经在TCP / IP中实现的服务器,但我们现在要求协议也支持UDP。 发送的每个UDP数据报都包含我需要解码的所有内容,因此它是一个非常简单的回复和响应系统,数据报中的数据由换行符分隔。 启动服务器时引导程序的代码如下所示: //SETUP UDP SERVER DatagramChannelFactory udpFactory = new NioDatagramChannelFactory(Executors.newCachedThreadPool()); ConnectionlessBootstrap udpBootstrap = new ConnectionlessBootstrap(udpFactory); udpBootstrap.setOption(“sendBufferSize”, 65536); udpBootstrap.setOption(“receiveBufferSize”, 65536); udpBootstrap.setOption(“receiveBufferSizePredictorFactory”, new AdaptiveReceiveBufferSizePredictorFactory()); udpBootstrap.setOption(“broadcast”, “true”); udpBootstrap.setPipelineFactory(new ServerPipeLineFactoryUDP()); udpBootstrap.bind(new InetSocketAddress(hostIp, 4000)); 管道代码是: class ServerPipeLineFactoryUDP implements ChannelPipelineFactory { private final static ExecutionHandler EXECUTION_HANDLER = new ExecutionHandler(new OrderedMemoryAwareThreadPoolExecutor(ScorpionFMS.THREAD_POOL_COUNT, 0, 0)); public ServerPipeLineFactoryUDP() { } @Override public […]