gpt4 book ai didi

java - 创建一个发生在与 AtomicBoolean 的关系之前

转载 作者:行者123 更新时间:2023-11-30 06:32:05 26 4
gpt4 key购买 nike

阅读此代码AsyncSubscriber.java :编码器使用 AtomicBoolean 创建 Happens Before 关系,我想知道:

1_是否相当于使用synchronized block ?看起来这些行 if (on.get()) 不能确保该 block

try {
final Signal s = inboundSignals.poll(); // We take a signal off the queue


if (!done) { // If we're done, we shouldn't process any more signals, obeying rule 2.8
// Below we simply unpack the `Signal`s and invoke the corresponding methods
if (s instanceof OnNext<?>)
handleOnNext(((OnNext<T>)s).next);
else if (s instanceof OnSubscribe)
handleOnSubscribe(((OnSubscribe)s).subscription);
else if (s instanceof OnError) // We are always able to handle OnError, obeying rule 2.10
handleOnError(((OnError)s).error);
else if (s == OnComplete.Instance) // We are always able to handle OnComplete, obeying rule 2.9
handleOnComplete();
}
}

一次将由 1 个线程执行。

事实上,当on.get()返回true时,什么会阻止另一个线程进入临界区?!

2_它比同步块(synchronized block)更高效吗? (假设 AtomicBoolean 使用 Volatile 变量)

这里是代码部分:

    // We are using this `AtomicBoolean` to make sure that this `Subscriber` doesn't run concurrently with itself,
// obeying rule 2.7 and 2.11
private final AtomicBoolean on = new AtomicBoolean(false);

@SuppressWarnings("unchecked")
@Override public final void run() {
if(on.get()) { // establishes a happens-before relationship with the end of the previous run
try {
final Signal s = inboundSignals.poll(); // We take a signal off the queue
if (!done) { // If we're done, we shouldn't process any more signals, obeying rule 2.8
// Below we simply unpack the `Signal`s and invoke the corresponding methods
if (s instanceof OnNext<?>)
handleOnNext(((OnNext<T>)s).next);
else if (s instanceof OnSubscribe)
handleOnSubscribe(((OnSubscribe)s).subscription);
else if (s instanceof OnError) // We are always able to handle OnError, obeying rule 2.10
handleOnError(((OnError)s).error);
else if (s == OnComplete.Instance) // We are always able to handle OnComplete, obeying rule 2.9
handleOnComplete();
}
} finally {
on.set(false); // establishes a happens-before relationship with the beginning of the next run
if(!inboundSignals.isEmpty()) // If we still have signals to process
tryScheduleToExecute(); // Then we try to schedule ourselves to execute again
}
}
}
// What `signal` does is that it sends signals to the `Subscription` asynchronously
private void signal(final Signal signal) {
if (inboundSignals.offer(signal)) // No need to null-check here as ConcurrentLinkedQueue does this for us
tryScheduleToExecute(); // Then we try to schedule it for execution, if it isn't already
}

// This method makes sure that this `Subscriber` is only executing on one Thread at a time
private final void tryScheduleToExecute() {
if(on.compareAndSet(false, true)) {
try {
executor.execute(this);
} catch(Throwable t) { // If we can't run on the `Executor`, we need to fail gracefully and not violate rule 2.13
if (!done) {
try {
done(); // First of all, this failure is not recoverable, so we need to cancel our subscription
} finally {
inboundSignals.clear(); // We're not going to need these anymore
// This subscription is cancelled by now, but letting the Subscriber become schedulable again means
// that we can drain the inboundSignals queue if anything arrives after clearing
on.set(false);
}
}
}
}

3_安全吗?

4_它是否常用于此目的(创建发生在关系之前)?

最佳答案

是的,写入/读取 AtomicBolean 建立了发生在关系之前:

compareAndSet and all other read-and-update operations such as getAndIncrement have the memory effects of both reading and writing volatile variables.

由于您没有发布完整的代码,并且我们不知道它到底是如何使用的,所以很难说它是否是线程安全的,但是:

ad 1. 它不等同于同步块(synchronized block) - 线程不等待

ad 2. 是的,它可能会更高效,但是compareAndSwap 没有义务得到volatile 的支持。变量 - 这是实现的数据。

ad 3. 很难说,但事实是 run是一个公共(public)方法,会暴露一些错误的可能性,例如,如果两个线程将调用 run直接当 go值为 true 。从我的角度来看,直接在run中进行compareAndSwap会更好。方法,但我不知道所有要求,所以这只是一个建议。

ad 4. 是的,常用的是 AtomicBoolean。

关于java - 创建一个发生在与 AtomicBoolean 的关系之前,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45902711/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com