同步

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,即使关键字为​​也是如此。