Skip to content

[Medium] Fix unsynchronized clear() in RamCache causing race condition #26

Description

@bitflicker64

Bug

RamCache.clear() performs two separate mutations — this.map.clear() then this.queue.clear() — with no lock held across both operations.

Root Cause

The clear() method does:

  1. this.map.clear()
  2. this.queue.clear()

Between step 1 and step 2, a concurrent write() call can insert a new entry into both map and queue. After queue.clear() runs, the map has the new entry but the queue doesn't — they are permanently out of sync.

Race Condition Walkthrough

  • Thread A (clear): map.clear() -> map is now empty
  • Thread B (write): map.put(id, queue.enqueue(...)) -> entry added to both
  • Thread A (clear): queue.clear() -> removes B's entry from queue only

Result: map contains the new entry but queue does not. Subsequent access() calls find the node in the map, try to queue.remove(node), get null back — silent cache miss for data that is actually present.

Proposed Fix

Minimal fix (add synchronized to clear()):

@Override
public synchronized void clear() {
    if (this.capacity() <= 0 || this.map.isEmpty()) {
        return;
    }
    this.map.clear();
    this.queue.clear();
}

Complete fix — introduce a ReadWriteLock:

  • clear() acquires the write lock
  • write(), access(), remove() acquire the read lock

Files to Touch

File Change
RamCache.java Add synchronization to clear()

Test Impact

1 test file needs a new concurrent test:

  • CacheTest.java (in hugegraph-test module)

No existing tests should break — adding synchronized is purely additive.

Acceptance Criteria

  • clear() is synchronized (or uses ReadWriteLock)
  • Concurrent write() + clear() does not leave map and queue out of sync
  • New test in CacheTest.java verifies the fix under concurrent access
  • All existing tests pass

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions