我遇到了以下问题。以最简单的方式,我在我的Web应用程序中有一个servlet和一个java类。现在java类迭代列表,为每个元素应用一些逻辑。我还有一个计数器来跟踪处理过的元素。我将计数器值传播到servlet可以通过setter访问的另一个类。从我的servlet中我执行AJAX调用以检索处理元素的数量并显示进度条。
int counter = 0;
...
for(SecurityForWorkflow securityForWorkflow : newSecuritiesForWorkflow) {
...
WorkflowManager.getInstance().setProcessedSecurities(counter);
counter++;
...
}
问题是进度条不平滑,可能从1到56到100。 我的猜测是,JIT通过看到没有人访问(获取)计数器并将增量移出循环来以某种方式优化流程。我得出了这个结论,因为在调试循环时一切顺利(我假设JIT在调试时无法改变流程)但是当我运行它并将值输出到带有时间戳的日志文件时,计数器立即从0递增到总值/同时即使循环运行20秒(170次迭代)。
我的问题是,是否可以禁用代码段的JIT优化(例如通过注释,但谷歌搜索表明它不是)或者可能通过语言构造/技巧强制执行非优化(我尝试声明变量static ,volatile,把循环放在一个synchronized块中,每次都在一个新生成的线程中调用setter,把setter放在try-catch的finally块中,还有一些我现在不记得了,如果我放一个Thread.sleep就可以工作(1000)在循环中)。
UPDATE :这是循环的代码
我还用WorkflowManager.getInstance().setProcessedSecurities(counter);
位更新了WorkflowManager.getInstance().incProcessedSecurities();
,结果是相同的
for(SecurityForWorkflow securityForWorkflow : newSecuritiesForWorkflow) {
ManualInteractionEntity manualInteractionEntity = null;
BondEntityStatus createdBond = null;
LegEntity createdLeg = null;
isin = securityForWorkflow.getIsin();
try {
automatedSecurityBuildingStatus = securityBuilder.createBondEntity(
isin, businessDay);
if(automatedSecurityBuildingStatus.getBondEntityStatus()
.getAssetType() != null
&& automatedSecurityBuildingStatus.getBondEntityStatus()
.getEcbStatus() != null) {
createdBond = automatedSecurityBuildingStatus.getBondEntityStatus();
}
else {
removeFromSecuritiesForWorkflow.add(securityForWorkflow);
}
} catch(Exception e) {
NabsLogger.getInstance().log(Level.WARNING, String.format("Exception"
+ " when creating security with isin: %s", isin), e);
continue;
}finally{
WorkflowManager.getInstance().incProcessedSecurities();
}
try {
createdLeg = createdBond.getLegEntities().get(0);
} catch (Exception e) {
createdLeg = createdBond.getLegEntityStatus();
}
if (createdBond.getSetupStatus().equals(
Constants.MANUAL_INTERACTION_NEEDED)) {
manualInteractionEntity = new ManualInteractionEntity();
securityForWorkflow.addStatus(
SecurityForWorkflow.STATUS_MANUAL_INTERACTION_NEEDED);
manualInteractionEntity.setId(createdBond.getId());
manualInteractionEntity.setCreation(true);
Set<String> manualInteractionFields = automatedSecurityBuildingStatus
.getManualInteractionRuleResults().keySet();
manualInteractionEntity.setManualInteractionFields(
new ArrayList<String>(manualInteractionFields));
manualInteractionEntities.add(manualInteractionEntity);
} else if (createdBond.getSetupStatus().equals(
Constants.CREATED_AUTOMATICALLY)) {
securityForWorkflow.addStatus(
SecurityForWorkflow.STATUS_AUTOMATICALLY_BUILT);
}
PaymentDateCalculatorModel paymentDateCalculatorModel =
new PaymentDateCalculatorModel();
paymentDateCalculatorModel.setAllDates(createdBond);
PaymentProfileCalculatorModel paymentProfileCalculatorModel =
new PaymentProfileCalculatorModel();
paymentProfileCalculatorModel.setAllPayments(createdBond);
entities.add(createdBond);
legs.add(createdLeg);
}
感谢。
答案 0 :(得分:-1)
尝试制作计数器volatile
,或者更好地制作AtomicInteger
。