2017-08-27 62 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 –