创建A发生关系之前用的AtomicBoolean
读该代码AsyncSubscriber.java: 编码器使用的AtomicBoolean创建偏偏关系之前,我想知道:创建A发生关系之前用的AtomicBoolean
1_是否等同于使用synchronized块? 它看起来该 if (on.get())
不到风度的线确保块
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_它是否比同步块更高效? (考虑到的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 etablishes关系之前发生的情况:
compareAndSet和如 getAndIncrement所有其他的读取和更新操作同时具有阅读的记忆效应和写作 volatile变量。
既然你没有张贴整个代码,我们不知道这是怎么究竟用它很难说,如果它是线程安全与否,而是:
广告1.它是不等于同步块 - 线程不会等待
ad 2.是的,它可能更有效率,但compareAndSwap没有义务支持volatile
变量 - 这是实现的数据。
广告3.很难说,但事实证明,run
是一个公共方法暴露了错误的某种可能性,例如,如果两个线程调用run
直接当go
将有true
值。从我的角度来看,直接在run
方法中进行compareAndSwap会更好,但我不知道所有要求,所以这只是一个建议。
ad 4.是的,通常使用AtomicBoolean。
我编辑我的问题,对我来说,它接缝,这种情况dosn't确保提及的块是由一个线程在执行时? –
它确保,但只有当'run'方法不被'tryScheduleToExecute'以外的其他任何东西调用或调度时。 –
关于你的第二个anwser,我打开AtomicBoolean的实现它使用volatile boolean –
https://stackoverflow.com/questions/3848070/atomicboolean-vs-synchronized-block https://stackoverflow.com/questions/28155245/atomicboolean-vs-synchronized-block-whats-the-difference – 2017-08-27 07:46:34
由于' on'永远不会设置为'true',那么代码将永远不会运行。 – Andreas
我没有过去所有的代码,我只是添加了其余 –