我正在学习 Java 中的多线程。我编写了一个简单的通用存储类,它始终按升序存储对象。我现在想让它线程安全。一种方法(可能也是最简单的方法)是:
// LinkedList implementation of a typical BST
class MyStorage<T> { // implements a comparable and some other interfaces not required by the MRE
private BSTreeNode rootNode;
// in case of duplicates, the occurrence property of the BSTreeNode is utilized
public synchronized boolean add(T);
public synchronized boolean delete(T);
public synchronized boolean search(T);
}
当前保存的存储:1,2,3,4,5,6,7,9
但是,我觉得这不是一个好主意,因为一个线程擦除 6,另一个线程添加 8 是完全可以接受的,无论它们以什么顺序调用或中断,存储都会给出正确的结果。我觉得需要的是对同一个值专门执行 2 个不同的操作。
这是我目前的想法:
// same sync block for every(or just add/delete?) function
public boolean add(T value) {
synchronized(/*some sort of mutex on the value object instead of on this*/) {
}
}
我该如何实现这一目标?
您在对其应用任何类型的操作时已锁定该对象。这段代码可能有帮助。
import java.util.HashMap;
import java.util.Map;
class MyStorage<T> {
private final Map<T, Object> locks = new HashMap<>();
private final Map<T, BSTreeNode> data = new HashMap<>();
public boolean add(T value) {
synchronized (getLock(value)) {
// Add logic here
}
return true;
}
public boolean delete(T value) {
synchronized (getLock(value)) {
}
return true;
}
public boolean search(T value) {
synchronized (getLock(value)) {
// Search logic here
}
return true;
}
private Object getLock(T value) {
// Ensure that there is a lock for each value
return locks.computeIfAbsent(value, k -> new Object());
}
}