从一篇Blog看两个并发编程错误
来源:互联网 发布:json new date 格式化 编辑:程序博客网 时间:2024/04/29 02:13
发现公司支付宝接入的代码有点神奇,在网上搜索了下,找到原始版本。估计有不少人都是抄那份代码的。
原文在:http://blog.csdn.net/simdanfeg/article/details/9011603 Android支付接入(一):支付宝
但是代码里有两个明显的并发问题,尽管在Android下可能不会有问题。
下面摘抄一段:
public class MobileSecurePayer { <strong>Integer lock = 0; </strong> // 和安全支付服务建立连接 private ServiceConnection mAlixPayConnection = new ServiceConnection (){ public void onServiceConnected (ComponentName className, IBinder service){ // // wake up the binder to continue. // 获得通信通道 <strong>synchronized (lock)</strong>{ mAlixPay = IAlixPay.Stub.asInterface (service); lock.notify (); } } // 实例一个线程来进行支付 new Thread (new Runnable (){ public void run (){ try{ // wait for the service bind operation to completely // finished. // Note: this is important,otherwise the next mAlixPay.Pay() // will fail. // 等待安全支付服务绑定操作结束 // 注意:这里很重要,否则mAlixPay.Pay()方法会失败 synchronized (lock){ <strong> if (mAlixPay == null) lock.wait (); </strong> }
第一个问题:用Integer做lock对象。
在Oracle JDK里,Integer是有会缓存的,从-128 到127的Integer会缓存到内部的一个IntegerCache,所以两个Integer可能会是同一个对象。还可以用-XX:AutoBoxCacheMax参数来设置cache的范围。
另外,即使Integer的内部实现是没有缓存的,对于像Integer lock = 0; 这样的代码,编绎器可能会把它变成一个变量,然后共享这样一个常量。
所以可能不同的类,会共享了一个synchronized (lock)对象,线程的并发度大大降低,甚至可能会有死锁。
同理,像Boolean,Float,Long这种类型都是不适合用来做lock对象的。
最好的办法是直接 Object lock = new Object(); 。
第二个问题:wait方法没有在while循环里。
绝大部分情况下,object.wait()方法都应该while循环来判断条件变量。因为wait()函数可能会因为spurious wakeup而返回。
spurious wakeup请参考另一篇blog:http://blog.csdn.net/hengyunabc/article/details/27969613
另外直接看JDK的文档,里面就说得很清楚:
//As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop: synchronized (obj) { while (<condition does not hold>) obj.wait(); ... // Perform action appropriate to condition }
最后,支付宝的接入应该去官方的网站找文档。不过这网站不好找,在支付宝的主页貌似没有链接过去。。
https://openhome.alipay.com/doc/docIndex.htm
- 从一篇Blog看两个并发编程错误
- 从Java看多核并发编程的2.0趋势
- 从并发编程角度看Java内存模型
- 从需求理论看Blog
- 【并发编程】从Java内存模型看并发数据共享与线程安全
- 从异常看错误
- 从今天起,每天写一篇blog!
- 看动画学并发编程
- 看动画学并发编程
- java多线程和并发编程(三)--- 从JVM并发看CPU内存指令重排序(Memory Reordering)
- 从12306看海量并发网站架构
- 从JDK源码看Java并发特性
- 从netstat看网络编程
- 看《Java并发编程实践》的笔记
- 第一篇blog不知道从何写起
- #mark#从今天起的第一篇blog!
- [乱弹]从一篇新闻看电子杂志的标准化
- 推荐一篇文章“从半空看虚拟化”
- 25岁了,是学linux运维还是编程好呢?求指点下 ..
- Lua学习笔记1:开发环境搭建(windows和linux)
- 为什么符号链接跨操作系统?
- java中常用的工具类——MD5
- 输入一个字符串,将其各个字符对应的ASCII值加5后,输出结果。
- 从一篇Blog看两个并发编程错误
- 网络工程师和linux运维、学哪个好呢?
- 螺旋矩阵
- java中常用的工具类——File工具类
- 网络工程师能赚多少钱???
- hdu 2138——How many prime numbers
- 1054. The Dominant Color
- qt编译过程中出现错误:arm-linux-g++ could not found
- 要离职,公司竟招些坑爹的网管,主管那边过不去。网管--一个烂大 ...