Java 如何在线程安全的情况下读取向量的最后X个条目?
我有一个包含向量的单例记录器。来自外部的对象可以通过调用singletonLogger.append(字符串数据)将信息附加到此向量,并通过调用singletonLogger.getLogEntries()读取整个向量,该函数返回字符串。 最好使用int参数重载getLogEntries方法,例如getLogEntries(intx),以便只获取最后的x个条目,而不是整个日志 如果不考虑多线程,这将很容易,例如:Java 如何在线程安全的情况下读取向量的最后X个条目?,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,我有一个包含向量的单例记录器。来自外部的对象可以通过调用singletonLogger.append(字符串数据)将信息附加到此向量,并通过调用singletonLogger.getLogEntries()读取整个向量,该函数返回字符串。 最好使用int参数重载getLogEntries方法,例如getLogEntries(intx),以便只获取最后的x个条目,而不是整个日志 如果不考虑多线程,这将很容易,例如: String getLogEntries(int x) { int size =
String getLogEntries(int x) {
int size = vector.size();
for(int i = size; i > (size - x); i--) {
// StringBuilder.append(vector.elementAt....
}
}
但当然,在考虑多线程时,这并不是真正安全的。假设向量在通过上述方法确定其大小后不久被另一种方法清除,则循环将崩溃
另一方面,我不想将整个方法标记为synchronized,因为循环处理可能会持续5-10秒。这将阻止所有试图调用记录器方法的代码,对吗
有没有其他方法可以可靠地获取向量的最后x个元素
谢谢编辑
Vector有一个应该工作并同步的线程,但这不能解决在另一个线程中清除Vector
的问题。当使用子列表()
从向量的末尾读取时,可以使用并获得readLock()
,当需要调用clear()
时,可以使用并获得writeLock()
(保证独占访问)。如果您的后台线程正在将日志条目写入磁盘或其他内容,它应该计算写入的行数,然后获取writeLock()
,并从列表的前面删除它们,而不是调用clear()
。这将限制锁下的时间以提高效率
您也可以考虑维护自己的内部队列,以便可以具体控制同步。这样可以更容易地从队列中清除较早的条目。然后,您可能还需要一个ReadWriteLock
。Edit
Vector有一个应该工作并同步的线程,但这不能解决在另一个线程中清除Vector
的问题。当使用子列表()
从向量的末尾读取时,可以使用并获得readLock()
,当需要调用clear()
时,可以使用并获得writeLock()
(保证独占访问)。如果您的后台线程正在将日志条目写入磁盘或其他内容,它应该计算写入的行数,然后获取writeLock()
,并从列表的前面删除它们,而不是调用clear()
。这将限制锁下的时间以提高效率
您也可以考虑维护自己的内部队列,以便可以具体控制同步。这样可以更容易地从队列中清除较早的条目。那么,您也可能需要一个<代码> Read RealObjs<代码>, 是否考虑将相关元素复制到一个新的<代码>向量<代码>中,在<代码>同步< /代码>块中,然后在一个外部进行处理? 是否考虑将相关元素复制到新的<代码>向量< /代码>中的<代码>同步< /代码>块中?然后在1之外处理它们?你能让向量同步吗?嗯。Vector
类已经按照定义进行了同步。你能不能让向量同步?嗯。Vector
类已经按照定义进行了同步。感谢大家。我知道向量已经是线程安全的,但我认为这并不能解决我的问题。想象:子列表(vector.size()-x,vector.size())
。当执行子列表时,不能保证这些索引仍然有效,对吗?好的,这确保了两个索引是一致的。但不能保证向量仍然包含这些标记,因为它们是在另一个时间确定的,然后执行子列表方法。edit:hm,您的注释消失了:如果在对基础向量进行任何更改后使用此方法返回的列表,您将获得并发修改异常。这使得它非常不适合多线程应用程序。谢谢大家。我知道向量已经是线程安全的,但我认为这并不能解决我的问题。想象:子列表(vector.size()-x,vector.size())
。当执行子列表时,不能保证这些索引仍然有效,对吗?好的,这确保了两个索引是一致的。但不能保证向量仍然包含这些标记,因为它们是在另一个时间确定的,然后执行子列表方法。edit:hm,您的注释消失了:如果在对基础向量进行任何更改后使用此方法返回的列表,您将获得并发修改异常。这使得它非常不适合多线程应用程序。