日期:2014-05-20  浏览次数:20676 次

万能的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中都使用该副本