Java 同步ScheduledFuture.cancel()方法
这个例子是从 我不明白为什么作者同步了stopEnergySource方法,它只是取消了ScheduledFuture任务,该任务由RequirementTask变量表示?没有其他方法使用此变量。 同步Future.cancel调用是可取的做法,还是仅用于ScheduledFutureJava 同步ScheduledFuture.cancel()方法,java,multithreading,concurrency,synchronized,scheduledexecutorservice,Java,Multithreading,Concurrency,Synchronized,Scheduledexecutorservice,这个例子是从 我不明白为什么作者同步了stopEnergySource方法,它只是取消了ScheduledFuture任务,该任务由RequirementTask变量表示?没有其他方法使用此变量。 同步Future.cancel调用是可取的做法,还是仅用于ScheduledFuture public class EnergySource { //... private static final ScheduledExecutorService replenishTimer = E
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() {
//...
}
}
公共类能源资源{
//...
专用静态最终计划执行器服务计时器=
执行器。newScheduledThreadPool(10);
私有调度的未来任务;
私有能源(){}
私有void init(){
RefullTask=RefullTimer.scheduleAtFixedRate(新的可运行(){
public void run(){infully();}
},0,1,时间单位为秒);
}
公共静态能源资源创建(){
最终能源能源能源=新能源();
energySource.init();
返回能源;
}
公共长getUnitsAvailable(){
//...
}
公共长getUsageCount(){
//...
}
公共能源(最终长单位){
//...
}
public synchronized void stopennergysource(){//**synchronized**的用途是什么?
补充任务。取消(false);
}
私有无效补充(){
//...
}
}
没有其他方法使用此变量。同步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() {
//...
}
}
我相信代码的作者试图强制设置内存障碍,以防不同的线程试图调用从一开始就启动作业的stopEnergySource()
但是,如果是这种情况,那么init()
方法也应该是同步的
,因为它们没有安全地发布任务
字段。该字段不是final
,编译器允许create(…)
返回,但稍后继续EnergySource
对象的构造和初始化
如果多个线程正在创建和停止这些对象,您可以在
stopEnergySource(…)
中轻松获得NPE,即使上面有synchronized
关键字。这没有多大意义。ScheduledFuture
不需要synchronized
关键字。更糟糕的是,如果这是该类中唯一的synchronized
代码,则该同步没有任何效果,这使得它更容易引起误解。查看完整的代码后,我可以告诉您infull()
方法中AtomicLong
的用法也被破坏(“检查然后执行”反模式).这不是很好的代码。。。我认为这是一个错误。所以Future.cancel()
根本不需要同步,或者这取决于您的情况?