不行,受不了了,我要记录下这个 bug

我们在使用 java 中使用线程 Thread 的时候,在 run(){  } 里面的如果要传递参数给函数,一般,编译系统都会提示我们,要将这个参数尽可能地设置为 final,即常量,一旦定义就不能再被修改的。

这样的要求真是极好的!

除了定义为 final 就不能传了吗?非也,我们可以把 需要传递的变量弄为 global 全局的,但是!!问题往往就是这样出现了。

大家看下下面这段代码。

 1 for(int u=0;u<result.length;u++){
 2     final int picIndex=u;
 3     final Bitmap bitmap = result[picIndex];
 4     new Thread(new Runnable() {
 5         @Override
 6         public void run() {
 7                InternetHelper.uploadPic
 8                (   // 批量 上传 图片,此静态函数 必须要 加 synchronized
 9                    "http://zzzzzzzz.php?"+"account="+userAccountTemp+"&postid="+userPostId,
10                     bitmap,              //修改之前这里直接用 result[u]
11                     ""+picIndex+".jpg"   //修改之前,picIndex 是全局的
12                );
13          }
14      }).start();
15 }

这是我项目里面的真实代码,目的是为了把 Bitmap数组 result 里面的bitmap转为 jpg 传递到 服务器,就是上传图片,由于图片不可能是 1张,而且较大,700K左右/张,这是已经尽力压缩的情况了,所以需要多个线程来传。

在还没有把 picIndex、bitmap 弄为 final之前,说下我遇到的情况,result 里面总是有2张以上的不同图片 bitmap 数据,按照道理,执行完上述代码,共开了两个+线程,上传了两张以上的不同的图片。

但是,我在服务器里检测的时候,发现总是只上传了一张图片,就是说我把同一张图片,上传了几次!!然后我就开始打印 log 了,分别打印 u、和 bitmap.toString(),发现,在进入 线程之前,都是正常的,即不同。按道理我传递的也是不同的才对。uploadPic 函数是没问题的。

想了下,我觉得是线程搞的鬼了,它在执行函数内的代码时,还来不及执行完, for 循环已经进行完毕,那么 对应的 参数也就跟着变了,但是等 函数内代码再去内存中取这个数的时候,就取到了 后面的。

于是乎,把会变得,要传的参数,全改为 final,问题解决。

时间: 2024-11-18 16:19:54

不行,受不了了,我要记录下这个 bug的相关文章

记录下我曾经那些认为的小想法

每隔一段时间,脑袋瓜子就会冒出一些自认为是小想法. 这篇文章就记录下我以前的一些小想法以及以后的小想法,一种想记录下来,一直也没有机会和时间.直到现在一琢磨,赶紧记录下来吧,也许很多时候的灵光一闪真是一个不错的idea.记录下来前面想起的和现在以及以后的idea,因此这篇文章会不断地实时更新,越来越完善. IDea1 2012年,刚步入高中的时候的第二学期,依稀记得那时候的智能手机还没有想象的普遍,在校门口当时接触了第一台智能机,一个高仿iphone 4s的手机,当时和同学一狠心每人买了一台.当

谷歌眼镜记录下的真实朝鲜

今年四月份,Kenny Zhu利用谷歌眼镜在朝鲜拍下了许多照片,记录了真实的朝鲜,这也是全世界首次使用可穿戴设备拍摄的朝鲜照片. 这些照片与普通相机拍摄的朝鲜照片并没有太大不同,但是由于是第一人称视角,拍摄位置更加随意,观众更能体会身在其中的感觉,仿佛是自己在亲身游览这一神秘国度. 在朝鲜,拍摄照片有很严格的规定,游客只允许拍摄反应朝鲜正面形象的照片,Kenny Zhu也是冒险拍了一些不被允许的照片,这也多亏了谷歌眼镜拍照不太引人注意的特点. 谷歌眼镜记录下的真实朝鲜,布布扣,bubuko.co

Winform程序当运行exe 停止响应时 如何记录下日志?

通常我们在写程序时会对程序中可能出错的程序段用try catch 捕捉获取.这样程序运行中一旦有bug.用户也能快速定位到错误段去了解出错原因. 遇到的问题: 但是遇到这样的情况 有时候没有用到try catch 时出错了.程序直接停止响应.这时候对于开发人员就比较伤脑筋.无法快速debug C#程序如何捕捉未try/catch的异常--不弹"XXX已停止工作"报错框? 解决方法: 1:在Main主程序中添加代码 设置 Windows 窗体线程和其他线程上发生的异常发生异常的事件处理的

记录下自己(持续更新)

本身就是个怀旧的人,无聊的时间记录下自己生活的点点滴滴, 更无聊的时候看下喽!那就从衣食住行乐随便说一下啦.(个人观点)互联网时代了,说没有隐私也可以,说有隐私也行,就看别人怎么对你了,我不喜欢对事情 下定论,我觉着一切皆有可能.(想把衣食住行什么的分开来写,试了几次,格式总是不太好,也不太喜欢拘束,就随便加了个分隔线,写到哪就算哪了) --------------------------------------------------------------------------分隔线---

记录下UIButton的图文妙用和子控件的优先显示

UIButton的用处特别多,这里只记录下把按钮应用在图文显示的场景,和需要把图片作为按钮的背景图片显示场景: 另外记录下在父控件的子控件优先显示方法(控件置于最前面和置于最后面). 先上效果图: 1.当在某个地方既需要显示图片,还需要显示文字,另外还要有点击功能的时候,这时按钮是个很好的选择. 按钮中的图片和文字的距离可以自由调整,图片的也可以上下左右翻转.日常项目中像这些场景都是很容易碰到的. 按钮图文设置.图文位置移动.按钮中图片翻转示例代码: /** 测试图文并茂的按钮,图文移动 */

记录下zend studio 的xdebug 在调试安装

没有单步调试 看不到变量的变化过程,是没法提高DEBUG效率的.折腾了好久终于把xdebug+zendstudio搞定了.虽然网上有教程,但实践起来 还是碰到了些问题,在此记录下. 1,安装zend stuido 这里就不说这个了,必须的 2,安装phpstudy 主要是要安装php,apahce.没有本地服务器,怎么能调试呢. 3,xdebug 安装 在这里,我根据网上很多教程去下载了xdebug.但其实不需要,你装好了phpstudy就已经默认有了xdebug.dll.为什么不建议去网上再下

datetime各种处理。记录下,备不时之需。

1. 获取某段日期范围内的所有日期 /// <summary>    /// 获取某段日期范围内的所有日期,以数组形式返回     /// </summary>     /// <param name="dt1">开始日期</param>     /// <param name="dt2">结束日期</param>     /// <returns></returns>

C#值类型以及默认值记录下

C#的值类型有bool,byte,sbyte,decimal,double,float,int,uint,long,string等 如果我们擅长使用默认值,可以帮助我们减少带来赋值及代码编写. 比如我我经常赋值: int i=0; 下面都是各个值类型的默认值: bool=>false byte,sbyte=>0 int,uint,long=>0 string,object=>null short,ushort=>0 特别说明:Datetime,因为它是结构体,必须初始化,我们

用路由设置,记录下

routes.MapRoute( "Default_a", "huhangfei/{pageindex}-{state}-{size}.html", new { controller = "Home", action = "Index", pageindex = 1, state = 0 ,size=0}, new { pageindex = @"\d+", state = @"\d+"