2017-08-27 24 views
1

读该代码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_通常用于此目的(创建关系之前发生)?

+0

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

+0

由于' on'永远不会设置为'true',那么代码将永远不会运行。 – Andreas

+0

我没有过去所有的代码,我只是添加了其余 –

回答

1

是,写/读AtomicBolean etablishes关系之前发生的情况:

compareAndSet和如 getAndIncrement所有其他的读取和更新操作同时具有阅读的记忆效应和写作 volatile变量。

既然你没有张贴整个代码,我们不知道这是怎么究竟用它很难说,如果它是线程安全与否,而是:

广告1.它是不等于同步块 - 线程不会等待

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

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

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

+0

我编辑我的问题,对我来说,它接缝,这种情况dosn't确保提及的块是由一个线程在执行时? –

+1

它确保,但只有当'run'方法不被'tryScheduleToExecute'以外的其他任何东西调用或调度时。 –

+0

关于你的第二个anwser,我打开AtomicBoolean的实现它使用volatile boolean –