下面是一个实现:
import java.util.*;
public class Mutex<T> {
private final List<T> list = new ArrayList();
public synchronized Lock acquireLock(
T value
) throws InterruptedException {
if(list.contains(value)) {
while(list.contains(value)) {
this.wait();
}
} else {
list.add(value);
}
return new Lock(value);
}
public class Lock {
private final T value;
public Lock(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public void release() {
synchronized(Mutex.this) {
list.remove(value);
Mutex.this.notifyAll();
}
}
}
}
下面是一个示例用法来检查可操作性:
public class Test {
private Mutex mutex = new Mutex();
public static void main(String[] args) {
Test test = new Test();
Thread t1 = new Thread(() -> {
try {
test.test("SameValue");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
});
t1.setName("Thread 1");
Thread t2 = new Thread(() -> {
try {
test.test("SameValue");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
});
t2.setName("Thread 2");
t1.start();
t2.start();
}
public void test(String value)
throws
InterruptedException {
Lock lock = mutex.acquireLock(value);
try {
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName());
} finally {
lock.release();
}
}
}
关于你们的执行,
我会使用Set而不是List来保存值(我假设这些值有适当的equals/hashcode,这样才有意义):List#contains方法在O(n)中,如果同时使用大量IBAN,这可能会很昂贵。
另外,您应该避免使用synchronize(this)(与synchronized关键字on方法相同)。
例如:
为了解决您的问题,我使用如下内容:
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Locks<T> {
private final Lock lock = new ReentrantLock();
//a Bimap from guava might be better here if you have the dependency
//in your project
private final Map<Reference<?>, T> valuePerReference = new HashMap<>();
private final Map<T, Reference<Lock>> locks = new HashMap<>();
private final ReferenceQueue<Lock> lockReferenceQueue = new ReferenceQueue<>();
public Locks() {
final Thread cleanerThread = new Thread(new Cleaner());
cleanerThread.setDaemon(true);
cleanerThread.start();
}
/**
* @param value the value the synchronization must be made on
* @return a lock that can be used to synchronize block of code.
*/
public Lock getLock(T value) {
lock.lock();
try {
return getExistingLock(value).orElseGet(() -> createNewLock(value));
} finally {
lock.unlock();
}
}
private Optional<Lock> getExistingLock(T value) {
return Optional.ofNullable(locks.get(value)).map(Reference::get);
}
private Lock createNewLock(T value) {
//I create ReentrantLock here but a Supplier<Lock> could be a parameter of this
//class to make it more generic. Same remark for SoftReference below.
final Lock lock = new ReentrantLock();
final Reference<Lock> reference = new SoftReference<>(lock, lockReferenceQueue);
this.locks.put(value,reference);
this.valuePerReference.put(reference,value);
return lock;
}
private void removeLock(Reference<?> reference) {
lock.lock();
try {
final T value = valuePerReference.remove(reference);
locks.remove(value);
} finally {
lock.unlock();
}
}
private class Cleaner implements Runnable {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
final Reference<? extends Lock> garbaged = lockReferenceQueue.remove();
removeLock(garbaged);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
}
import java.util.concurrent.locks.Lock;
public class Usage {
private final Locks<String> locks = new Locks<>();
public void doSomethind(String iban) {
final Lock lock = locks.getLock(iban);
lock.lock();
try {
//.. do something with your iban
} finally {
lock.unlock();
}
}
}
因为普罗米修斯topk返回的结果比预期的要多,而且因为https://github.com/prometheus/prometheus/issues/586需要客户端处理,而这些处理尚未通过https://github.com/grafana/grafana/issues/7664提供,所以我正在尝试对我的类似问题进行不同的近期解决方案。 在我的特殊情况下,我想要绘制的大多数度量值在大多数情况下都
问题内容: 经过一些帮助MSChart-强制从Origin绘制折线图]后,我设法将以下MSSQL查询放在一起,以用于折线图。 但是,我有一个问题。该查询返回类似以下内容的内容: 这意味着我每天都在阅读,而实际上每个不同的值仅需要一行。在每种情况下,我都希望它第一次出现,因此对于上面的示例,我希望查询返回: 我看了看似是基于类似前提的几个问题,但是所有答复都是针对特定情况而量身定制的(有些甚至使用L
问题内容: 我有一个在while循环中生成一堆数据的python脚本。我需要将此数据写入CSV文件,因此它是按列而不是行写入的。 例如,在脚本的循环1中,我生成: 我需要它来反映在我的csv脚本中,如下所示: 在第二个循环中,我生成: 我需要它来像这样在我的csv文件中查找: 依此类推,直到while循环结束。有谁能够帮助我? 编辑 while循环可以持续超过100,000个循环 问题答案: 之所
问题内容: 我想使用abs()对元组进行排序,而无需实际将元组的元素更改为正值。 根据python Wiki(https://wiki.python.org/moin/HowTo/Sorting/#Key_Functions),sorted(list,key =)函数假定使用参数 key 进行排序,而实际上并未更改清单。但是,abs()只需要int(),如果我需要这样做,我还没有想办法将元组变成i
我正在尝试使用创建一个6乘12的矩阵 虽然这样可以工作,但问题是内部数组实际上都引用了相同的对象。 我希望(并且期望)的值为。 如何强制填充给定参数的按值复制(例如:是我的例子中的参数)而不是按引用复制?
问题内容: 让我们举个例子 我想在列表中附加值,但列表的值也已更改。 我想我不知道为什么会这样(python通过引用传递列表)。 我的问题是“如何通过值传递它,以使添加不会更改中的值?” 问题答案: