首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在与AtomicBoolean的关系之前创建一个

在与AtomicBoolean的关系之前创建一个
EN

Stack Overflow用户
提问于 2017-08-27 07:38:22
回答 1查看 279关注 0票数 1

阅读此代码AsyncSubscriber.java:编码器使用AtomicBoolean创建关系之前发生的事件,我想知道:

1_是否等同于使用同步块?看起来,if (on.get())的行并不能确保

代码语言:javascript
复制
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();
        }
      }

将由一个线程在时间上执行。

实际上,当on.get()返回true时,是什么阻止另一个线程进入关键部分?!

2_是否比同步块更有效?(假设AtomicBoolean使用Volatile变量)

在这里,代码的一部分:

代码语言:javascript
复制
    // 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_是否通常用于此目的(创建关系之前发生的事件)?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-27 08:57:37

是的,写/读给AtomicBolean建立关系之前就会发生:

compareAndSet和所有其他读和更新操作(如getAndIncrement )都具有读取和写入易失性变量的内存效果。

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

Ad1.它不等同于同步块线程不等待

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

很难说,但run是一种公共方法,这一事实暴露了一些错误的可能性,例如当go的值为true时,两个线程将直接调用true。从我的角度来看,最好直接在compareAndSwap方法中执行run,但是我不知道所有的需求,所以这只是一个建议。

广告4 :是的,AtomicBoolean是常用的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45902711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档