同步

2

Code below是板缺例如,從"Programming Concurrency on the JVM: Mastering Synchronization, STM, and Actors" book同步

我不明白爲什麼筆者同步stopEnergySource方法,剛剛取消ScheduledFuture任務,這代表由replenishTask變量?沒有其他方法使用這個變量。 是否需要實踐來同步Future.cancel調用或它只需要ScheduledFuture?

public class EnergySource { 
    //... 
    private static final ScheduledExecutorService replenishTimer = 
    Executors.newScheduledThreadPool(10); 
    private ScheduledFuture<?> replenishTask; 

    private EnergySource() {} 

    private void init() { 
    replenishTask = replenishTimer.scheduleAtFixedRate(new Runnable() { 
     public void run() { replenish(); } 
    }, 0, 1, TimeUnit.SECONDS); 
    } 

    public static EnergySource create() { 
    final EnergySource energySource = new EnergySource(); 
    energySource.init(); 
    return energySource; 
    } 

    public long getUnitsAvailable() { 
    //... 
    } 

    public long getUsageCount() { 
    //... 
    } 

    public boolean useEnergy(final long units) { 
    //... 
    } 

    public synchronized void stopEnergySource() { // what for **synchronized** is? 
    replenishTask.cancel(false); 
    } 

    private void replenish() { 
    //... 
    } 
} 
+1

這沒什麼意義...... – assylias

+1

'ScheduledFuture'不需要'synchronized'關鍵字。更糟糕的是,如果這是該類中唯一的「同步」代碼,那麼這種同步沒有任何效果,這使得它更具誤導性。 – Holger

+1

查看完整的代碼後,我可以告訴你,'replenish()'方法內AtomicLong的用法也被破壞了(「check-then-act」反模式)。 – Holger

回答

0

有使用這個變量沒有其他方法。同步Future.cancel調用或ScheduledFuture只需要它是否可取?

我相信,代碼的作者試圖強迫的情況下,內存的障礙在不同的線程試圖調用stopEnergySource(),在最初開始工作。

但是,如果是這種情況,則init()方法應該是​​,因爲他們沒有做replenishTask領域的安全發佈。該字段不是final,並且允許編譯器返回create(...),但稍後繼續構建和初始化EnergySource對象。

如果多個線程正在創建和停止這些對象,您可以很容易地在stopEnergySource(...)中獲得NPE,即使關鍵字爲​​也是如此。