我在Linux上有一个多线程应用程序。我通过解析/ net / proc / tcp文件来推断主叫用户的ID。基本上,操作系统会在系统文件中添加本地/远程地址和端口信息,我们尝试将其与http套接字详细信息进行匹配。
private String identifyCaller(HttpServletRequest httpServletRequest) {
IdService idService = new IdService();
OptionalInt uid = idService.getUID(
httpServletRequest.getLocalAddr(),
httpServletRequest.getLocalPort(),
httpServletRequest.getRemoteAddr(),
httpServletRequest.getRemotePort());
...
和IdService类类似
class IdService {
private static Pattern pattern = Pattern.compile("\\s*\\d+: ([0-9A-Fa-f]+):([0-9A-Fa-f]+) ([0-9A-Fa-f]+):([0-9A-Fa-f]+) ([0-9A-Fa-f]{2}) [0-9A-Fa-f]+:[0-9A-Fa-f]+ [0-9A-Fa-f]+:[0-9A-Fa-f]+ [0-9A-Fa-f]+\\s+([0-9]+).+");
private final String ipV4Path;
private final String ipV6Path;
public IdService() {
this.ipV4Path = Constants.PROC_NET_TCP_PATH;
this.ipV6Path = Constants.PROC_NET_TCP6_PATH;
}
public OptionalInt getUID(String localAddr, int localPort, String remoteAddr, int remotePort) {
OptionalInt uid;
try (BufferedReader br = new BufferedReader(new FileReader(ipV4Path))) {
String line;
while ((line = br.readLine()) != null) {
uid = getUID(line, localPort, remotePort, remoteAddr);
if (uid.isPresent()) {
return uid;
}
}
} catch (IOException e) {
log.error("Exception reading {} file. ", ipV4Path, e);
// Handle
}
private OptionalInt getUID(String line, String remoteAddr, int reqLocalPort, int reqRemotePort) {
Matcher matcher = pattern.matcher(line);
if (!matcher.matches()) {
return OptionalInt.empty();
}
int count = matcher.groupCount();
...
// More rules and if match then returns a matched field
}
}
我看到,除非我使用IdSevice的新实例,否则对UID的扫描将返回空Optional(当前套接字不匹配)。 “ / net / proc / tcp”中的内容发生了变化,但是我想知道是什么导致此线程不安全。所有工作似乎都发生在局部线程变量上,因此我以前使用的是单例对象,但结果不正确。成员变量是常量String对象,唯一的静态对象是最终成员。那么,什么导致线程不安全呢?