java - 阻止java线程共享数据?

标签 java thread-safety

我有一个应用程序(服务器端),位于端口上并监听客户端连接。 建立连接后,应用程序将启动一个解析器(另一个线程)来处理该连接。

我的问题是,在某些时候(因为解析可能需要很长时间)服务器应用程序会在其他线程正在处理时启动一个新线程。这是一种期望的行为,本身不是问题。发生的情况是新线程似乎从旧线程读取了一些状态变量,因此行为错误。

大致来说,解析器的作用是这样的: 客户端总是发送两个数据包;第一个基本上是敲门数据包,第二个是真实数据包。 我阅读了第一个数据包,如果我决定接受它,我会将其放入一个变量中,以便可以读取下一个数据包。

在所描述的场景中,第一个线程读取敲门数据包并验证它。 下一个数据包到达(在同一线程上)并且解析开始。

与此同时,另一个解析器被创建并等待第一个数据包; 然后发生的事情(问题)是它检查验证变量(对于这个线程来说应该是假的)并且发现它没问题(它从仍在执行的前一个线程中读取)并继续解析敲击敲击数据包,就好像它是数据包一样。

我正在寻找一种完全消除数据共享的方法。我使用以下类来跟踪 session 状态:

public class SessionInfo {

    private Constants.PacketValidity validity;
    private int packetSize;
    private String IMEI;
    private int packetReportedSize;
    private Constants.PacketType packetType;
    private int codec;
    private int records;
    private boolean valid;
    private Constants.ResponseType responseType;
    private String clientIP;
    private int serverPort;
    private Date parseInit;
    private Date parseEnd;
}

除此之外,该类还有很多 setter 和 getter。

解析器将此对象的实例作为私有(private)字段。

我如何实现这个目标?

最佳答案

the parser has a instance of this object as a private field.

这是你的问题。解决方案是创建一个新的 SessionInfo 并将其作为方法参数传递给解析器,然后将其传递给进一步的方法调用。一旦执行此操作,对 session 状态的引用将位于当前线程执行的本地。

如果您的解析器包含更多在解析过程中更新的私有(private)属性,您还需要提取这些属性。将它们组合在一个私有(private)子类中,并在调用解析时创建该类的实例将是该问题的可能解决方案。

关于java - 阻止java线程共享数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6993701/

相关文章:

java - 观察者结合模板模式

java - 在 Java SQLite 中执行查询时出现 SQLException

java - 应用程序关闭时发出通知

java - 当你用小 X 关闭 GUI 时

java - Double Check Lock 在此 java 代码上不起作用?

java - 如何在我的 Web 应用程序中分析调用的方法

java - 如何在 Java 中为 2D 游戏构建 Tiled map ?

c++ - 我们是否需要将 volatile 关键字和互斥锁一起用于线程安全?

java - java List适合addAll和clear上的线程安全的什么方法

java和线程: very strange behaviour