如何在线程安全的情况下读取向量的最后X个条目?

时间:2012-02-17 16:25:47

标签: java multithreading thread-safety

我有一个包含矢量的单例记录器。来自外部的对象可以通过调用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个元素吗?

由于

2 个答案:

答案 0 :(得分:2)

修改

Vector有一个sublist method应该可以工作并且可以同步,但这并不能解决在另一个线程中清除Vector的人。您可以使用ReadWriteLock并在readLock()的末尾使用Vectorsublist()(保证独占访问权限)时writeLock()获取clear() writeLock()需要调用1}}。如果您的后台线程正在将日志条目写入磁盘或其他内容,则应计算写入的行数,然后获取clear()并从列表前面删除它们而不是调用ReadWriteLock。这将限制锁定下的时间更有效。

您也可以考虑维护自己的内部队列,以便可以专门控制同步。这可以更容易清除队列中的早期条目。那么你也可能需要一个{{1}}。

答案 1 :(得分:1)

您是否考虑将相关元素复制到Vector块中的新synchronized,然后在一个区域外处理它们?