java - 我可以通过参数同步方法吗
问题描述
我可以通过参数同步方法吗?
例如 - 我让人使用某种方法,我想为人做一些操作,但是如果很少有线程为同一个人调用这个方法,我想一个一个地做。
private void dosomething(Long id, Person person) {
dosomethingelse(id, person);
}
如何只为同一个id一一调用dsomethingelse(id,person)?但我希望可以多线程调用不同 id-s 的这段代码
我写了这段代码,但这里可能有问题,或者有更好的地方。
public static class LatchByValue <T> {
public void latch(T value, ConsumerWithException<T> consummer) throws Exception {
CountDownLatch latch = new CountDownLatch(1);
try {
CountDownLatch previousLatch = null;
// we are checking if another thread is already calling this method with the same id
// if sync has CountDownLatch so another thread is already calling this method
// or we put our latch and go on
while ((previousLatch = sync.putIfAbsent(value, latch)) != null) {
try {
// we are waiting for another thread, we are waiting for all threads that put their latch before our thread
previousLatch.await();
} catch (InterruptedException e) {
return;
}
}
consummer.accept(value);
} finally {
latch.countDown();
sync.remove(value, latch);
}
}
private ConcurrentHashMap<T, CountDownLatch> sync = new ConcurrentHashMap<>();
}
例子:
LatchByValue<Long> latch = new LatchByValue<>();
private void dosomething(Long id, Person person) {
latch.latch(
id,
currentId -> { dosomethingelse(currentId, person); }
);
}
解决方案
使用 a 的问题CountdownLatch
是您不能“增加”计数,因此您需要在使用现有锁存器时替换它,这会使代码复杂化。
您可以改为使用带有Semaphore
一个许可证的许可证,这将允许您以更简单的方式做同样的事情。
Semaphore s = sync.computeIfAbsent(value, x -> new Semaphore(1, true));
s.acquire(); //this blocks and throws InterruptedException, which you need to handle
try {
consummer.accept(value);
} finally {
s.release();
}
推荐阅读
- javascript - 如何在asp查询中使用js字符串?
- unix - grep \t 匹配字母“t”,而不是制表符
- angular - 我如何从 Angular 应用程序访问服务器文件系统
- java - 可以使用数组对象参数的 Listview 适配器吗?
- stata - egen 的 seq() 函数出现故障?
- c# - 如何使用 StreamWriter 输出变量的值
- intellij-idea - Mockito 处于调试模式,断点结果为 WrongTypeOfReturnValue
- node.js - NPM 从分支获取 master 安装,而不是分支
- excel - Excel图表,如何对相似的类别进行分组?
- regex - 通过正则表达式拆分输入字符串