我有一个包含矢量的单例记录器。来自外部的对象可以通过调用singletonLogger.append(String data)将信息附加到此向量,并通过调用返回字符串的singletonLogger.getLogEntries()来读取整个向量。 使用int参数重载getLogEntries方法会很好,例如getLogEntries(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个元素吗?
由于
答案 0 :(得分:2)
修改强>
Vector有一个sublist
method应该可以工作并且可以同步,但这并不能解决在另一个线程中清除Vector
的人。您可以使用ReadWriteLock
并在readLock()
的末尾使用Vector
和sublist()
(保证独占访问权限)时writeLock()
获取clear()
writeLock()
需要调用1}}。如果您的后台线程正在将日志条目写入磁盘或其他内容,则应计算写入的行数,然后获取clear()
并从列表前面删除它们而不是调用ReadWriteLock
。这将限制锁定下的时间更有效。
您也可以考虑维护自己的内部队列,以便可以专门控制同步。这可以更容易清除队列中的早期条目。那么你也可能需要一个{{1}}。
答案 1 :(得分:1)
您是否考虑将相关元素复制到Vector
块中的新synchronized
,然后在一个区域外处理它们?