我有一个应用程序(服务器端),它位于端口上并侦听客户端连接。 一旦建立连接,应用程序就会启动一个处理该连接的解析器(另一个线程)。
我的问题是,在某些时候(因为解析可能需要很长时间),服务器应用程序会在处理其他线程时启动新线程。这是一种理想的行为,本身并不是问题。发生的事情是新线程似乎从旧线程读取一些状态变量,因此行为错误。
松散地,解析器的作用是: 客户端总是发送两个数据包;第一个基本上是敲敲包,第二个是真正的数据包。 我读了第一个,如果我决定接受它,我把它放在一个变量中,以便可以读取下一个数据包。
在描述的场景中,第一个线程读取knock knock数据包并对其进行验证。 下一个数据包到达(在同一个线程上)并开始解析。
同时创建另一个解析器并等待其第一个数据包; 然后发生的问题(问题)是它检查验证变量(对于这个线程应该是假的)并且它发现它是正常的(它从前一个线程读取,它仍然在执行)并继续解析敲击敲打包好像是数据包。
什么是lokoing是一种完全消除数据共享的方法。我正在使用以下类来跟踪会话状态:
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;
}
除此之外,该课程还有许多制定者和吸气剂。
解析器将此对象的实例作为私有字段。
我将如何实现这一目标?
答案 0 :(得分:2)
您需要确保两个单独的线程使用两个单独的SessionInfo
实例。
最简单的方法是创建一个新的解析器实例,然后创建一个新的SessionInfo
实例。一旦你确定他们有单独的实例,你应该没事。
答案 1 :(得分:2)
解析器将此对象的实例作为私有字段。
这是你的问题。解决方案是创建一个新的SessionInfo
并将其作为方法参数传递给解析器,并将其传递给进一步的方法调用。执行此操作后,对会话状态的引用将是当前线程执行的本地引用。
如果您的解析器包含更多在解析期间更新的私有属性,则还需要提取这些属性。将它们组合在一个私有子类中,并在调用解析时创建该类的实例将是解决该问题的可能方法。