阻止java线程共享数据?
我有一个应用程序(服务器端)位于端口上并侦听客户端连接。 建立连接后,应用程序将启动一个解析器(另一个线程)来处理该连接。
我的问题是,在某些时候(因为解析可能需要很长时间),服务器应用程序会在其他线程正在处理时启动一个新线程。这是一种期望的行为,本身不是问题。发生的情况是,新线程似乎从旧线程读取了一些状态变量,因此行为错误。
粗略地说,解析器所做的事情是这样的: 客户端总是发送两个数据包;第一个基本上是敲门数据包,第二个是真实数据包。 我阅读了第一个数据包,如果我决定接受它,我会将其放入一个变量中,以便可以读取下一个数据包。
在我描述的场景中,第一个线程读取敲门数据包并验证它。 下一个数据包到达(在同一线程上)并且解析开始。
与此同时,另一个解析器被创建并等待第一个数据包; 然后发生的事情(问题)是它检查验证变量(对于这个线程来说应该是假的)并且发现它没问题(它从仍在执行的前一个线程中读取)并继续解析敲击敲击数据包,就好像它是数据包一样。
我正在寻找一种完全消除数据共享的方法。我使用以下类来跟踪会话状态:
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。
解析器有一个该对象的实例作为私有字段。
我将如何实现这一目标?
I have an application (server side) that sits on a port and listens for client connections.
Once a connection is made, the app launches a parser (another thread) that deals with that connection.
My problem is that at some points (because the parsing can take long) the server app launches a new thread while other is being processed. This is a desired behavior, not a problem per se. what happens is that the new thread seems to read some state-variable from the old thread and therefore acts wrongly.
Loosely, what the parser does is this:
the client always sends two packets; the first is basically an knock knock packet and the second is the real data packet.
I read the first, and if i decide to accept it i put that in a variable, so that the next packet can be read.
On the scenario am describing, the first thread reads the knock knock packet and validates it.
The next packet arrives (on the same thread) and the parsing starts.
In the mean time, another parser is created and it waits for its first packet;
What then happens (the problem) is that it checks for the validation variable (which should be false for this thread) and it finds it to be ok (it reads from the previous thread, which is still executing) and proceeds to parse the knock knock packet as if it were the data packet.
What am lokoing for is a way to completely eliminate data sharing. am using the following class to keep track of the session state:
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;
}
apart from that, the class has a bunch of setters and getters.
the parser has a instance of this object as a private field.
How would i achieve this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是你的问题。解决方案是创建一个新的 SessionInfo 并将其作为方法参数传递给解析器,然后将其传递给进一步的方法调用。一旦执行此操作,对会话状态的引用将位于当前线程执行的本地。
如果您的解析器包含更多在解析过程中更新的私有属性,您还需要提取这些属性。将它们组合在一个私有子类中,并在调用解析时创建该类的实例将是该问题的可能解决方案。
This is your problem. A solution would be to create a new
SessionInfo
and pass it as a method argument to the parser, passing it on to further method calls. Once you do this the reference to the session state will be local to the current thread execution.If your parser contains more private attributes that are updated during parsing, you need to extract these also. Combining them in a private subclass and creating an instance of that class when you are called to parse would be a possible solution to that problem.
您需要确保两个单独的线程使用两个单独的 SessionInfo 实例。
最简单的方法可能是创建一个新的解析器实例,该实例又创建一个新的 SessionInfo 实例。一旦你确保它们有单独的实例,你应该没问题。
You need to make sure that the two separate threads use two separate
SessionInfo
instances.The easiest way to do this is probably to create a new parser instance, which in turn creates a new
SessionInfo
instance. Once you make sure that they have separate instances, you should be fine.