我想使用 Swing 作为界面,用 Java 编写一个聊天应用程序。
我提出了一个想法(在 MadProgrammer 的帮助下),但我不确定这是否是解决此问题的最佳方法。
在main
线程中有两个Blockinqueue
队列,一个用于传入消息,一个用于传出消息。
有四个线程,两个用于传出消息,两个用于传入消息,各一个用于处理 GUI 和套接字。
传出消息的线程:
ActionListener (Swing)
:当用户在 GUI 中单击“发送”时触发。该线程将新消息添加到传出队列并在其上触发notifyAll()
。socketOutgoing
:有权访问套接字。在传出队列上使用wait()
hibernate ,直到收到通知。通过套接字发送 Outgoing Queue 中的新消息,然后再次返回 sleep 状态。
传入消息的线程:
socketIncoming:
可以访问套接字。不断检查是否有新的 套接字中的消息(如何?)。当有新消息时,将其添加到 传出队列并在其上触发notifyAll()
。Swingworker displayIncoming
: hibernate ,并在传入队列上使用wait()
,直到收到通知。在 GUI 中显示新消息,然后再次返回 sleep 状态。
虽然这在理论上是可行的,但为此设置四个线程似乎有点困惑(而且不可靠)。
有更实用的解决方案吗?
future 读者请注意:我对 socketIncoming
的描述被误导了:不可能“连续检查套接字中的新消息”。
当您调用ObjectInputStream#readObject()
并且没有新消息时,它只是等待或“阻塞”,直到新消息到达。无法事先检查是否有新消息到达。 See this question 。
最佳答案
如果我正在考虑做类似的事情,我可能会设置两个队列,一个传出队列和一个传入队列。这些将用于“暂存”消息。
这个想法是,传出消息将被放入传出队列中,当Thread
能够做到这一点时,它将弹出下一条消息并发送它。当队列为空时,它只会“等待”直到有新消息可用。
这个概念对于传入队列来说是相反的。 Thread
将读取消息并将其推送到传入队列中。
其他一些进程(可能是 SwingWorker
)将监视队列并弹出它的下一条消息,并将其与 GUI 重新同步。
您可能会发现Concurrency in Swing有一定用处。
底层协议(protocol)的实际工作方式将决定更多细节
关于使用 Swing 的 Java 聊天应用程序(概念),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30277029/