简体   繁体   中英

How to read the last X entries of a vector while being thread safe?

I have a singleton logger that contains a vector. Objects from outside can append information to this vector by calling singletonLogger.append(String data) and read the whole vector by calling singletonLogger.getLogEntries() which returns a string. It would be nice to overload the getLogEntries-method with an int-parameter, eg getLogEntries(int x), to be able to get only the last x entries instead of the whole log.

Without regarding mutliple threads, this would be easy, something like:

String getLogEntries(int x) {

int size = vector.size();

for(int i = size; i > (size - x); i--) {

    // StringBuilder.append(vector.elementAt....

 }
}

But of course, this is not really safe when taking multiple threads into account. Imagine the vector gets cleared by another method shortly after its size was determined by the method above, the loop will crash.

On the other hand, I do not want to mark the whole method as synchronized, because the loop processing could last 5 - 10 seconds. This would block all the code that is trying to call the logger's methods, right?

Is there another way to reliably get the last x elements of a vector?

Thanks

Edit

Vector has a sublist method that should work and be synchronized but that doesn't solve someone clearing the Vector in another thread. You could use ReadWriteLock and get a readLock() when reading from the end of the Vector using sublist() and a writeLock() (which guarantees exclusive access) when clear() needs to be called. If your background thread is writing the log entries to disk or something, it should count the number of line written, and then get a writeLock() and remove those from the front of the list instead of calling clear() . That would limit the time under the lock to be more efficient.

You might also consider maintaining your own internal queue so you can control the synchronization specifically. This may make it easier to clear the earlier entries from the queue. Then again you may need a ReadWriteLock for that as well.

您是否考虑过将相关元素复制到synchronized块中的新Vector中,然后在一个之外的地方进行处理?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM