java - 在同一端口轮询服务器 - 线程和 Java

标签 java multithreading sockets

我目前正忙于为早期版本的使命召唤 1 开发 IP 封禁工具。(显然这些版本中没有实现这样的功能)。

我已经完成了一个单线程应用程序,但它对于多个服务器来说性能不够好,这就是我尝试实现线程的原因。

现在,每个服务器都有自己的线程。我有一个网络类,它有一个方法; “GetStatus”——这个方法是同步的。此方法使用 DatagramSocket 与服务器通信。由于此方法是静态和同步的,我不应该遇到麻烦并收到一大堆“地址已在使用”异常。

但是,我有第二种方法名为“SendMessage”。此方法应该向服务器发送消息。当“GetStatus”中已经有一个线程在运行时,如何确保不能调用“SendMessage”,反之亦然?如果我使两者同步,如果线程 A 在端口 99999 上打开一个套接字并调用“SendMessage”,而线程 B 在同一端口上打开一个套接字并调用“GetStatus”,我仍然会遇到麻烦吗? (游戏服务器通常托管在相同的端口上)

我想我真正追求的是一种使整个类同步的方法,以便单个线程一次只能调用和运行一个方法。

希望我试图完成/避免的事情在本文中得到明确说明。

非常感谢任何帮助。

最佳答案

Right now, each server has its own thread.

为什么在同一个应用程序中需要两个服务器?!?如果您将两个服务器分解为单独的应用程序,那么如果它们都尝试使用相同的端口,您仍然会遇到同样的问题……也就是说,您必须为每个服务器专用一个端口。如果确实是线程问题,请阅读下文以了解如何解决此问题。

两个线程不可能正确执行同一个类的同步方法...如果你有正确的同步那么就没有办法体验你的重新描述。你的类应该是这样的:

class Networking 
{
    public synchronized Status getStatus() {
        Status stat =  new Status();
        // ...
        // Get status logic
        // ...
        return stat;// return the status
    }

    public synchronized void sendMessage(Message msg) {
        // ...
        // Send the message logic
        // ...
    }
}

所以只要您在同一个Networking上调用这些方法instance(即您没有为每个线程创建一个单独的 Networking 类实例),那么您应该看不到任何问题。这是 synchronized 的内容关键字为你做:

First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads. (ref)

如果你想在 Networking 类的所有实例中同步方法,那么你需要使用同步语句:

class Networking 
{
    private static final Object lock = new Object();

    public synchronized Status getStatus() {
        synchronized(lock){
            Status stat =  new Status();
            // ...
            // Get status logic
            // ...
            return stat;// return the status
        }
    }

    public synchronized void sendMessage(Message msg) {
        synchronized(lock){
            // ...
            // Send the message logic
            // ...
        }
    }
}

关于java - 在同一端口轮询服务器 - 线程和 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2935865/

相关文章:

C# UDP 发送缓冲区

java - TCP 套接字关闭并重新绑定(bind)

java - org.apache.jasper.JasperException : The absolute uri: http://java. sun.com/jsp/jSTL/core 无法解析

java - JnetPcap:从脱机文件读取速度非常慢

java - 无法配置 Spring Security 加载 .loginPage ("/login")只有默认页面有效或发送到/templates/index.html

JavaFX:在单独的非 Controller 类中更新 UI

django - get_or_create() 线程安全吗

java - 简单递归和多重递归的区别

c# - Windows 服务意外终止

javascript - socket.io:点击时发出按钮的属性值?