Skip to content

Instantly share code, notes, and snippets.

@nil96
Created February 19, 2024 05:18
Show Gist options
  • Save nil96/3fa457659ebc4b43d0f05b5161f5c9a6 to your computer and use it in GitHub Desktop.
Save nil96/3fa457659ebc4b43d0f05b5161f5c9a6 to your computer and use it in GitHub Desktop.
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ConcurrentHashMap<K, V> {
private static final int DEFAULT_CAPACITY = 16;
private Entry<K, V>[] buckets;
private final ReentrantReadWriteLock[] locks;
public ConcurrentHashMap() {
this(DEFAULT_CAPACITY);
}
public ConcurrentHashMap(int capacity) {
this.buckets = new Entry[capacity];
this.locks = new ReentrantReadWriteLock[capacity];
for (int i = 0; i < capacity; i++) {
locks[i] = new ReentrantReadWriteLock();
}
}
public void put(K key, V value) {
int hash = hash(key);
ReentrantReadWriteLock lock = locks[hash % locks.length];
lock.writeLock().lock();
try {
Entry<K, V> entry = new Entry<>(key, value);
if (buckets[hash % buckets.length] == null) {
buckets[hash % buckets.length] = entry;
} else {
Entry<K, V> current = buckets[hash % buckets.length];
while (current.next != null) {
current = current.next;
}
current.next = entry;
}
} finally {
lock.writeLock().unlock();
}
}
public V get(K key) {
int hash = hash(key);
ReentrantReadWriteLock lock = locks[hash % locks.length];
lock.readLock().lock();
try {
Entry<K, V> current = buckets[hash % buckets.length];
while (current != null) {
if (current.key.equals(key)) {
return current.value;
}
current = current.next;
}
return null;
} finally {
lock.readLock().unlock();
}
}
public void remove(K key) {
int hash = hash(key);
ReentrantReadWriteLock lock = locks[hash % locks.length];
lock.writeLock().lock();
try {
Entry<K, V> current = buckets[hash % buckets.length];
Entry<K, V> prev = null;
while (current != null) {
if (current.key.equals(key)) {
if (prev == null) {
buckets[hash % buckets.length] = current.next;
} else {
prev.next = current.next;
}
return;
}
prev = current;
current = current.next;
}
} finally {
lock.writeLock().unlock();
}
}
private int hash(K key) {
return key.hashCode();
}
private static class Entry<K, V> {
final K key;
final V value;
Entry<K, V> next;
Entry(K key, V value) {
this.key = key;
this.value = value;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment