前一段时间在搞一个多线程的问题时,遇到了重复数据问题,后来经查阅是因为值传递引用传递问题。
1:按值传递是什么
指的是在方法调用时,传递的参数是按值的拷贝传递。
按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了。
2:按引用传递是什么
指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。
3:按引用传递的重要特点
传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。
说明:
在Java里面只有基本类型和按照下面这种定义方式的String是按值传递,其它的都是按引用传递。就是直接使用双引号定义字符串方式:String str = “Java私塾”;--------------------------------------------------------------------------------------------------
1、在给线程传值时需要注意对象为按引用传递,因此最好是先new一个对象然后再给线程传参。
如下:
public List<Future<FlightLowPrice>> getAdayLowPriceFlightNo(FlightOutQO flightOutQO,FlightParamQO flightParamQO){
LOG.info("开始获取一天各个航班次最低价:"+flightOutQO+flightParamQO);
List<Future<FlightLowPrice>> results = new ArrayList<Future<FlightLowPrice>>();
try {
//获取某天航班信息 或航班产品
SearchResult searchResult = this.getFlightInfo(flightOutQO, flightParamQO);
if(searchResult != null && searchResult.getSuccess() == 1){
//调用接口获取数据成功
ResultData data = searchResult.getData();
List<FlightItem> flightItems = data.getFlightItems();
if(flightItems != null && flightItems.size() > 0 ){ //存在航班信息
//获取一天航班最低价信息
List<List<SelectedFlightQO>> list = this.getAdayFlightSegments2(flightItems,flightParamQO);
//创建线程池
ExecutorService pool = Executors.newFixedThreadPool(POOL_SIZE);
for(List<SelectedFlightQO> selectedFlightList:list){
//因为对象是引用传递,需要重新new一个,否则线程都是操作的同一个对象,会出现数据重复现象
FlightOutQO flightOutQOThread = new FlightOutQO();
flightOutQOThread.setArrCityCode(flightOutQO.getArrCityCode());
flightOutQOThread.setDepCityCode(flightOutQO.getDepCityCode());
flightOutQOThread.setDepDate(flightOutQO.getDepDate());
flightOutQOThread.setSelectedFlights(selectedFlightList);
Callable<FlightLowPrice> c1 = new FeizhuOutDataCall(flightOutQOThread,flightParamQO, new FeizhuOutDataServiceImpl());
Future<FlightLowPrice> f = pool.submit(c1);
//线程返回结果放入results
results.add(f);
}
pool.shutdown();
}
}else{
//调用接口失败
LOG.error("调用接口失败,"+searchResult);
}
} catch (Exception e) {
e.printStackTrace();
LOG.error("获取一天各个航班次最低价出错:"+e.getMessage(),e);
}
return results;
}
上面方法在给线程传值时并未直接将flightOut传入,而是new了一个新的flightQOThread对象。
大家最好自己做个demo理解一下。
当时写这个地方的时候,出现重复数据困扰了我一天。。。。。。。
3:按引用传递的重要特点
传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。