Http Sessions在Tomcat中的生命周期(Http Sessions life cycle in Tomcat)
我有一项任务是向站点管理员显示用户名列表以及每个用户当前使用的tomcat会话数(以及其他一些支持相关信息)。
我将经过身份验证的用户保留为应用程序上下文属性,如下所示(不必要的细节)。
Hashtable<String, UserInfo> logins //maps login to UserInfo
UserInfo定义为
class UserInfo implements Serializable { String login; private transient Map<HttpSession, String> sessions = Collections.synchronizedMap( new WeakHashMap<HttpSession, String>() //maps session to sessionId ); ... }
每次成功登录都会将会话存储到此
sessions
映射中。sessionDestroyed()
中的HttpSessionsListener
实现从此映射中删除已销毁的会话,如果sessions.size()== 0,则从logins
删除UserInfo。一些用户不时会出现0个会话。 同行评审和单元测试表明代码是正确的。 所有会话都是可序列化的。
是否有可能Tomcat将会话从内存卸载到硬盘驱动器,例如,当存在一段不活动时间(会话超时设置为40分钟)? 从GC的角度来看,还有其他会话被“丢失”的情况,但是没有调用HttpSessionsListener.sessionDestroyed()吗?
J2SE 6,Tomcat 6或7独立,行为在任何操作系统上都是一致的。
I have a task to show to the site admin a list of user names and how many tomcat sessions are currently utilized by each user (along with some other support-related information).
I keep authenticated users as the application context attribute as follows (sparing unnecessary details).
Hashtable<String, UserInfo> logins //maps login to UserInfo
where UserInfo is defined as
class UserInfo implements Serializable { String login; private transient Map<HttpSession, String> sessions = Collections.synchronizedMap( new WeakHashMap<HttpSession, String>() //maps session to sessionId ); ... }
Each successful login stores the session into this
sessions
map. MyHttpSessionsListener
implementation insessionDestroyed()
removes the destroyed session from this map and, if sessions.size() == 0, removes UserInfo fromlogins
.From time to time I have 0 sessions showing up for some users. Peer reviews and unit testing show that the code is correct. All sessions are serializable.
Is it possible that Tomcat offloads sessions from memory to the hard drive, e.g. when there is a period of inactivity (session timeout is set to 40 minutes)? Are there any other scenarios where sessions are 'lost' from GC point of view, but HttpSessionsListener.sessionDestroyed() wasn't invoked?
J2SE 6, Tomcat 6 or 7 standalone, behaviour is consistent on any OS.
原文:https://stackoverflow.com/questions/5643171
最满意答案
如果我正确理解您的问题,您希望能够通过“密钥”前缀比较元素,而不是整个字符串内容。 如果是这样,实现自定义相等比较器将允许您轻松利用LINQ集算法。
这个节目......
class EqCmp : IEqualityComparer<string> { public bool Equals(string x, string y) { return GetKey(x).SequenceEqual(GetKey(y)); } public int GetHashCode(string obj) { // Using Sum could cause OverflowException. return GetKey(obj).Aggregate(0, (sum, subkey) => sum + subkey.GetHashCode()); } static IEnumerable<string> GetKey(string line) { // If we just split to 3 strings, the last one could exceed the key, so we split to 4. // This is not the most efficient way, but is simple. return line.Split(new[] { '*' }, 4).Take(3); } } class Program { static void Main(string[] args) { var l1 = new List<string> { "index1*index1*index1*some text", "index1*index1*index2*some text ** test test test", "index1*index2*index1*some text", "index1*index2*index2*some text", "index2*index1*index1*some text" }; var l2 = new List<string> { "index1*index1*index2*some text ** test test test", "index2*index1*index1*some text", "index2*index1*index2*some text" }; var eq = new EqCmp(); Console.WriteLine("Elements that are both in l1 and l2:"); foreach (var line in l1.Intersect(l2, eq)) Console.WriteLine(line); Console.WriteLine("\nElements that are in l1 but not in l2:"); foreach (var line in l1.Except(l2, eq)) Console.WriteLine(line); // Etc... } }
...打印以下结果:
Elements that are both in l1 and l2: index1*index1*index2*some text ** test test test index2*index1*index1*some text Elements that are in l1 but not in l2: index1*index1*index1*some text index1*index2*index1*some text index1*index2*index2*some text
If I understand your question correctly, you'd like to be able to compare the elements by their "key" prefix, instead by the whole string content. If so, implementing a custom equality comparer will allow you to easily leverage the LINQ set algorithms.
This program...
class EqCmp : IEqualityComparer<string> { public bool Equals(string x, string y) { return GetKey(x).SequenceEqual(GetKey(y)); } public int GetHashCode(string obj) { // Using Sum could cause OverflowException. return GetKey(obj).Aggregate(0, (sum, subkey) => sum + subkey.GetHashCode()); } static IEnumerable<string> GetKey(string line) { // If we just split to 3 strings, the last one could exceed the key, so we split to 4. // This is not the most efficient way, but is simple. return line.Split(new[] { '*' }, 4).Take(3); } } class Program { static void Main(string[] args) { var l1 = new List<string> { "index1*index1*index1*some text", "index1*index1*index2*some text ** test test test", "index1*index2*index1*some text", "index1*index2*index2*some text", "index2*index1*index1*some text" }; var l2 = new List<string> { "index1*index1*index2*some text ** test test test", "index2*index1*index1*some text", "index2*index1*index2*some text" }; var eq = new EqCmp(); Console.WriteLine("Elements that are both in l1 and l2:"); foreach (var line in l1.Intersect(l2, eq)) Console.WriteLine(line); Console.WriteLine("\nElements that are in l1 but not in l2:"); foreach (var line in l1.Except(l2, eq)) Console.WriteLine(line); // Etc... } }
...prints the following result:
Elements that are both in l1 and l2: index1*index1*index2*some text ** test test test index2*index1*index1*some text Elements that are in l1 but not in l2: index1*index1*index1*some text index1*index2*index1*some text index1*index2*index2*some text
相关问答
更多-
您似乎想要比较文件中的第一列并打印第二列中唯一的行。 使用comm : comm -13 <(awk '{print $1}' file1 | sort) <(awk '{print $1}' file2 | sort) 为了您的输入,它产生: somepackage4 You seem to want to compare the first column in the files and print the lines that are unique in the second one. Use c ...
-
C#lambda - 两个列表中内部列表的差异(除外)(C# lambda - Differences (Except) of inner lists inside two lists)[2023-11-20]
仅比较两个表,它将是: Default1.Columns .Select(x => x.Name) .Except(T1.Columns.Select(x => x.Name)); 为了比较两个模式,它将是: DefaultSchema .Zip(MyTables, (x, y) => new { Name = x.Name, MissingColumns = x.Columns.Select(x1 => x1.Name) ... -
比较两个列表并仅打印差异?(Comparing two lists and only printing the differences? (XORing two lists))[2023-06-29]
你基本上想要添加一个元素到你的新列表中,如果它存在于另一个而不存在的话。 这是一个紧凑的循环,可以做到这一点。 对于两个列表中的每个元素(将它们与list1+list2连接起来),我们添加元素,如果它不存在于其中之一: [a for a in list1+list2 if (a not in list1) or (a not in list2)] 你可以很容易地将它转换成一个更加非平凡的代码,并且像现在一样通过元素进行显式循环,但是老实说,我没有看到一点(不是那么重要): def xor(list1, l ... -
比较两个列表的差异(Compare two Lists for differences)[2022-04-11]
....但是我们如何找到第二个List中的等效类传递给下面的方法; 这是你的实际问题 您必须至少有一个不可变的属性,id或类似的东西来标识两个列表中的相应对象。 如果您没有这样的财产,就无法解决问题而没有错误。 您可以尝试通过搜索最小或逻辑更改来猜测相应的对象。 如果你有这样的财产,解决方案变得非常简单。 Enumerable.Join( listA, listB, a => a.Id, b => b.Id, (a, b) => CompareTwoClass_ReturnDifferen ... -
通过使用从numpy repeat和tile import numpy as np np.repeat(A,len(B))-np.tile(B,len(A)) Out[221]: array([-4, -5, -6, -3, -4, -5, -2, -3, -4, -1, -2, -3]) By using repeat and tile from numpy import numpy as np np.repeat(A,len(B))-np.tile(B,len(A)) Out[221]: arra ...
-
获取2个列表之间的差异(Get the differences between 2 lists)[2023-03-26]
要比较自定义数据类型列表的对象,您需要在类中实现IEquatable并覆盖GetHashCode() 检查此MSDN链接 你的班 public class PersonInfo : IEquatable{ public string Login { get; set; } public string FirstName { get; set; } public string LastName { get; set; } ... -
使用列表理解: In [42]: lst = [[1, 2], [3, 4], [1, 2], [5, 6], [8, 3], [2, 7]] In [43]: sublst = [[1, 2], [8, 3]] In [44]: [x for x in lst if x not in sublst] Out[44]: [[3, 4], [5, 6], [2, 7]] 或filter() : In [45]: filter(lambda x:x not in sublst,lst) Out[45]: ...
-
寻找集合中的差异(Finding Differences In Sets)[2021-11-27]
不,只是拥有这样的方法对你没有帮助。 您需要实现IEqualityComparer以传递给Enumerable.Except - 即使这样您的代码也需要: return List1.Except(List2, new SwitchComparer()).ToList(); 在CiscoSwitch覆盖Equals和GetHashCode可以更自然地完成这一操作 - 理想情况下,您也应该实现IEquatable 。 但是,值得注意的是,像这样的可变类型对于 ... -
对于一组差异, df['A'].map(set) - df['B'].map(set) For a set difference, df['A'].map(set) - df['B'].map(set)
-
找出两个列表中的差异(Finding differences in two lists)[2022-03-10]
如果我正确理解您的问题,您希望能够通过“密钥”前缀比较元素,而不是整个字符串内容。 如果是这样,实现自定义相等比较器将允许您轻松利用LINQ集算法。 这个节目...... class EqCmp : IEqualityComparer{ public bool Equals(string x, string y) { return GetKey(x).SequenceEqual(GetKey(y)); } public int GetHashCo ...