万能的CSDN,帮俺看看这个多线程的全局变量问题,多谢^_^
使用threadPool, 线程里有个全局变量A,出现了同一个线程访问不同的A值,因为下一个线程已经update A 了;
即使把update A 的方法synchronized, 还是同样的一问题
知道应该用synchronize, 可是怎么用呢?
1. call thread 的 codes:
for (int i = 0; i < list.size(); i++) {
Bank bank = (Bank)list.get(i);
String bankid = bank.getBank();
ReportParameters newReportParams = params;
try {
JasperReportThreadImpl jrThread = (JasperReportThreadImpl)ObjectCreator.createObject(report.getReportImplRef());
if (newReportParams != null){
newReportParams.setBankId(bankid);
}
jrThread.init(report, newReportParams, ReportImplConstants.REPORT_FORMAT_PDF);
System.out.println( ">>aft init, threadid : " + jrThread + " bankid : " +bankid ) ;
threadPool.assign(jrThread);
//Thread.sleep(1000);
} catch (Exception e) {
// TODO Auto-generated catch block
jreportImplLogger.error(e.getMessage());
jreportImplLogger.info(ReportLoggerConstants.REPORT_ERROR_03,new String [] {valueDate,reportId,reportGroupId});
}
}
threadPool.complete();
2.thread 里的update 方法
public synchronized void init(Report report,ReportParameters reportParams,String reportOutputFormat){
G3ContextLocator contextLocator = G3ContextLocator.getInstance();
BeanFactory baseFactory = contextLocator.getReportContext();
DataSource datasource = (DataSource) baseFactory.getBean("dataSource");
Connection connection = DataSourceUtils.getConnection(datasource);
this.report = report;
this.conn = connection;
this.reportParams = reportParams;
System.out.println(">>super init threadid : " + this + " bankid : "+ reportParams.getBankId() );
}
3.问题就出在reportParams,第一个thread run 的时候,对应的确是下个bank的信息,也就是说,第一个thread run的时候,第二个thread 已经update reportParams 了
希望我把问题说清楚了,谢谢先。。。
------解决方案--------------------
我表示看的很难过,虽然没看懂,按第三点汉字的理解给出我的建议:
1、在整个用到reportParams的地方和更新reportParams的地方使用同一把锁,保证其互斥访问,或者
2、在非更新reportParams的地方使用reportParams的副本,并且整个thread中都使用该副本