我有一个应用程序(服务器端),位于端口上并监听客户端连接。 建立连接后,应用程序将启动一个解析器(另一个线程)来处理该连接。
我的问题是,在某些时候(因为解析可能需要很长时间)服务器应用程序会在其他线程正在处理时启动一个新线程。这是一种期望的行为,本身不是问题。发生的情况是新线程似乎从旧线程读取了一些状态变量,因此行为错误。
大致来说,解析器的作用是这样的: 客户端总是发送两个数据包;第一个基本上是敲门数据包,第二个是真实数据包。 我阅读了第一个数据包,如果我决定接受它,我会将其放入一个变量中,以便可以读取下一个数据包。
在所描述的场景中,第一个线程读取敲门数据包并验证它。 下一个数据包到达(在同一线程上)并且解析开始。
与此同时,另一个解析器被创建并等待第一个数据包; 然后发生的事情(问题)是它检查验证变量(对于这个线程来说应该是假的)并且发现它没问题(它从仍在执行的前一个线程中读取)并继续解析敲击敲击数据包,就好像它是数据包一样。
我正在寻找一种完全消除数据共享的方法。我使用以下类来跟踪 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/