【发布时间】:2011-02-11 23:12:25
【问题描述】:
我正在尝试使用命名管道和 v01ver 在这个问题中描述的方法在 Windows 上提供 C# 应用程序和 Java 应用程序之间的通信:How to open a Windows named pipe from Java?
我在 Java 端遇到了一个问题,因为我有一个读取器线程一直在等待管道上的输入,当我尝试从我的主线程写入管道时,它会永远卡住。
final RandomAccessFile pipe;
try {
pipe = new RandomAccessFile("\\\\.\\pipe\\mypipe", "rw");
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
return;
}
Thread readerThread = new Thread(new Runnable() {
@Override
public void run() {
String line = null;
try {
while (null != (line = pipe.readLine())) {
System.out.println(line);
}
}
catch (IOException ex) {
ex.printStackTrace();
}
}
});
readerThread.start();
try { Thread.sleep(500); } catch (InterruptedException e) {}
try {
System.out.println("Writing a message...");
pipe.write("Hello there.\n".getBytes());
System.out.println("Finished.");
}
catch (IOException ex) {
ex.printStackTrace();
}
输出是:
正在写消息...然后它永远等待。
如何在等待另一个线程中的输入时写入命名管道?
【问题讨论】:
-
...你不能关掉也不能关掉阅读?仅当文件不在末尾时才读取,否则在
poll阻塞队列以等待写入;并最终使用单个线程。如果您有兴趣,我可以显示一个sn-p;但是我没有像这样的带有命名管道的 xp,一个简单的套接字是 10 倍易于管理 -
使用 JVisualVM 查看您的线程是在 O/S 级别还是在 Java 同步获取时阻塞可能会有所帮助。
-
与使用命名管道相比,您可能会发现使用套接字更具可扩展性(无论如何,命名管道在 Windows 中都是使用套接字实现的)您将找到更多有关如何使用它们的示例(因为它们使用得更频繁) 这应该对你有帮助。
-
@Peter Lawrey:Windows 中的命名管道不是使用套接字实现的。当客户端和服务器在同一台机器上时,它们使用共享内存进行 IPC,速度非常快。
-
@Peter,Java 管道(nio 管道)是通过 Windows 上的套接字和 Linux 上的操作系统管道实现的。 Windows 原生命名管道不是套接字及其 impl。不依赖于winsock。只是 java 不使用它们,因为不可能为套接字和 windows 管道注册相同的选择器。
标签: java multithreading deadlock named-pipes