Java 同步:如何让等待线程不执行同步任务
Java synchronization: how to have waiting threads not execute the synchronized task
假设我在 Java 中有一段代码要同步执行,但是当拥有锁的线程释放该锁时,我不希望等待线程执行任何同步代码更多的。我只想让他们等到同步代码完成 运行.
因此,当线程 1 进入同步代码(方法、代码块)时,它必须获得对该代码的锁定。任何后续线程都必须等待第一个线程完成 运行 代码。至此,定期代码同步。
但是在我的例子中,当第一个线程完成并释放锁时,我希望等待的线程跳过那段同步代码(代码更新所有线程使用的资源)。
我将如何使用同步功能在 Java 中创建它?目前我没有使用同步功能,而是使用一个持有锁(上下文)的并发集合,如下所示。然而,锁定的过程仍然需要以某种方式同步,因为两个线程能够在上下文上获得锁。
干杯!
凯耶尔德
/*
* A concurrently accessible set of contexts.
*/
private static final Set<String> LOCKED_CONTEXTS;
static {
LOCKED_CONTEXTS = ConcurrentHashMap.newKeySet(); // meanwhile, I replaced this with Collections.synchronizedSet(new HashSet<>())
}
...
if (!LOCKED_CONTEXTS.contains(context)) {
LOCKED_CONTEXTS.add(context);
log.debug("Locked context: {}", context);
try {
doTask();
} finally {
LOCKED_CONTEXTS.remove(context);
log.debug("Released context: {}", context);
}
} else {
log.debug("Waiting for context to be released: {}", context);
while (LOCKED_CONTEXTS.contains(context)) {
}
log.debug("The waiting is over, context is released: {}", context);
}
我想你想把锁和信号量结合起来。
tryLock
上锁
- 如果你明白了,那就去做吧。工作结束时,将信号量标记为完成
- 如果没有获取到,等待信号量完成
也许我不完全理解你的use-case,但据我所知,你想要一段代码在执行期间对所有触发器只运行一次,但如果有任何触发器则再次发生在上次执行之外 window.
这涵盖了吗?
class Work {
private volatile boolean done;
void queueWorkOnce() {
done = false;
actualWork();
}
private synchronized void actualWork() {
if (!done) {
//TODO: do work
done = true;
}
}
}
假设我在 Java 中有一段代码要同步执行,但是当拥有锁的线程释放该锁时,我不希望等待线程执行任何同步代码更多的。我只想让他们等到同步代码完成 运行.
因此,当线程 1 进入同步代码(方法、代码块)时,它必须获得对该代码的锁定。任何后续线程都必须等待第一个线程完成 运行 代码。至此,定期代码同步。
但是在我的例子中,当第一个线程完成并释放锁时,我希望等待的线程跳过那段同步代码(代码更新所有线程使用的资源)。
我将如何使用同步功能在 Java 中创建它?目前我没有使用同步功能,而是使用一个持有锁(上下文)的并发集合,如下所示。然而,锁定的过程仍然需要以某种方式同步,因为两个线程能够在上下文上获得锁。
干杯!
凯耶尔德
/*
* A concurrently accessible set of contexts.
*/
private static final Set<String> LOCKED_CONTEXTS;
static {
LOCKED_CONTEXTS = ConcurrentHashMap.newKeySet(); // meanwhile, I replaced this with Collections.synchronizedSet(new HashSet<>())
}
...
if (!LOCKED_CONTEXTS.contains(context)) {
LOCKED_CONTEXTS.add(context);
log.debug("Locked context: {}", context);
try {
doTask();
} finally {
LOCKED_CONTEXTS.remove(context);
log.debug("Released context: {}", context);
}
} else {
log.debug("Waiting for context to be released: {}", context);
while (LOCKED_CONTEXTS.contains(context)) {
}
log.debug("The waiting is over, context is released: {}", context);
}
我想你想把锁和信号量结合起来。
tryLock
上锁- 如果你明白了,那就去做吧。工作结束时,将信号量标记为完成
- 如果没有获取到,等待信号量完成
也许我不完全理解你的use-case,但据我所知,你想要一段代码在执行期间对所有触发器只运行一次,但如果有任何触发器则再次发生在上次执行之外 window.
这涵盖了吗?
class Work {
private volatile boolean done;
void queueWorkOnce() {
done = false;
actualWork();
}
private synchronized void actualWork() {
if (!done) {
//TODO: do work
done = true;
}
}
}