我有一个包含向量的单例记录器。外部对象可以通过调用singletonLogger.append(字符串数据)将信息附加到此向量,并通过调用singleton Logger.getLogEntry()读取整个向量,该函数返回一个字符串。最好用int参数重载getLogEntries方法,例如getLogEntrys(int x),以便只获取最后x个条目,而不是整个日志。
如果不考虑多线程,这将很容易,类似于:
String getLogEntries(int x) {
int size = vector.size();
for(int i = size; i > (size - x); i--) {
// StringBuilder.append(vector.elementAt....
}
}
但当然,当考虑多个线程时,这并不是真正安全的。想象一下,在上面的方法确定了向量的大小后不久,另一个方法就清除了向量,循环就会崩溃。
另一方面,我不想将整个方法标记为同步,因为循环处理可能持续5-10秒。这将阻止所有试图调用记录器方法的代码,对吧?
有没有其他方法可以可靠地得到向量的最后x个元素?
感谢
编辑
Vector有一个sublist
方法,它应该可以工作并同步,但这并不能解决有人在另一个线程中清除Vector
的问题。当使用sublist()
从Vector
的末尾读取时,可以使用ReadWriteLock
并获得readLock()
,当需要调用clear()
时,可以获得writeLock()
(保证独占访问)。如果后台线程正在将日志条目写入磁盘或其他什么地方,它应该计算写入的行数,然后获取writeLock()
并将其从列表的前面删除,而不是调用clear()
。这将限制被锁定的时间以提高效率。
您还可以考虑维护自己的内部队列,以便专门控制同步。这样可以更容易地从队列中清除较早的条目。再说一遍,你可能也需要一个ReadWriteLock
。
您是否考虑将相关元素复制到synchronized
块中的新Vector
,然后在块外处理它们?