Java发送消息线程

标签 java multithreading sockets dataoutputstream

我用 Java 编写了一个游戏,其中的客户端和服务器端使用套接字和数据输入/输出流。服务器端有时需要在“for”循环中向所有用户发送消息,但由于写入套接字可能会阻塞,因此我为每个向他发送消息的用户创建了一个线程(以及为每个监听的用户创建了另一个线程)传入消息)。发送线程是基于这个想法构建的:

private ArrayList<Object> messages = new ArrayList<Object>(),
                          newMessages = new ArrayList<Object>();

public void run() {
    while (true) {
        for (Object message: messages) {
            try {
                if (message instanceof Byte)
                    out.writeByte((Byte)message);
                else if (message instanceof Boolean)
                    out.writeBoolean((Boolean)message);
                else if (message instanceof String)
                    out.writeUTF((String)message);
                else if (message instanceof Integer)
                    out.writeInt((Integer)message);
                else if (message instanceof Long)
                    out.writeLong((Long)message);
            } catch (IOException e) {}
        }
        synchronized (newMessages) {
            messages.clear();
            messages.addAll(newMessages);
            newMessages.clear();
        }
    }
}

public void write(Object message) {
    synchronized (newMessages) {
        newMessages.add(message);
    }
}

不幸的是,run()方法一直在运行,所以我想插入一个 sleep 命令,以实现这样的效果:

private ArrayList<Object> messages = new ArrayList<Object>(),
                          newMessages = new ArrayList<Object>();

public void run() {
    while (true) {
        try {
            if (messages.isEmpty() && newMessages.isEmpty())
                sleep(0);
        } catch (InterruptedException e) {}
        for (Object message: messages) {
            try {
                if (message instanceof Byte)
                    out.writeByte((Byte)message);
                else if (message instanceof Boolean)
                    out.writeBoolean((Boolean)message);
                else if (message instanceof String)
                    out.writeUTF((String)message);
                else if (message instanceof Integer)
                    out.writeInt((Integer)message);
                else if (message instanceof Long)
                    out.writeLong((Long)message);
            } catch (IOException e) {}
        }
        synchronized (newMessages) {
            messages.clear();
            messages.addAll(newMessages);
            newMessages.clear();
        }
    }
}

public void write(Object message) {
    synchronized (newMessages) {
        newMessages.add(message);
        interrupt();
    }
}

但是,当有消息要发送时,这可能会导致线程进入休眠状态,例如,当 run() 方法进行 isEmpty() 检查后调用 write() 方法时,该方法返回 true,但已还没开始 sleep 。我真的想不出一种方法来避免 sleep(0) 这个问题,有人有想法吗?或者我在这方面走错了路?

非常感谢。

最佳答案

看看LinkedBlockingQueues 。您可以在代码中使用其中的一个来代替 messagesnewMessages 对象。

此类允许您从一个线程 A 添加项目并从另一个线程 B 读取项目。线程 B 将等待,直到线程 A 添加新消息。应该正是您所需要的。

关于Java发送消息线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13931856/

相关文章:

c++ - 为什么在Release模式下的while循环中我无法逃脱?

java - 从其他JAVA对象同步方法访问

Python套接字突然超时?

java - dnsjava - 如何使用 DNSSEC 验证进行查找?

java - Maven 术语——依赖和插件、存储库与 pluginRepository

java - tomcat服务器启动报错

c++ - 用 QT 线程解决运行时问题

c++ - 在 C++ 中通过 TCP 连接发送 Opencv Mat

使用套接字上传Java文件,需要上传文件的百分比?

java - 如何修复 java.lang.NoSuchMethodError : sun. security.ssl.Handshaker.setApplicationProtocols([Ljava/lang/String;)