浏览 1759 次
锁定老帖子 主题:一次同步不当的bug记录。
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-02-25
最后修改:2009-02-25
别急,别急,先保护现场,用另外一台服务器在调试模式下继续测试,想办法复现这个问题。 到了晚上,问题终于又出现了。打开远程调试,检查一下运行线程,发现有一大堆用于抓取外部数据的Servlet线程不动了。 原来,一条记录指向了一个公司内部ip地址,员工下班关机之后,无法获取该记录,导致装载延迟。 而我们的开发人员在这里为了避免同一资源的多次解析,用了一个全局的同步锁,一下子其他数据也无法装载。 问题代码: Object data = getFromCache...; if (data != null) { return data; } synchronized (LOCK) { Object data =getFromCache...; if (data != null) { return data; } data = buildData.. saveToCache... return data } 上面的代码看似还行,可是,确保了我们不会重复解析同一数据,但是,加锁加的不合适,一旦任何一个资源延迟,都将导致全部线程暂停。 给一下修改后的形式: private Map lockMap = new HashMap(); ..... protected String getCachedResource(String url) throws Exception { String key = url; Object data = getFromCache(key); if (data == null) { //获取资源对应的锁 Object lock = requireLock(url); synchronized (lock) { data = parser.parse(url); saveToCache(key, data); } //删除锁 lockMap.remove(key); } return (String) data; } private Object requireLock(Object key) { synchronized (lockMap) { Object lock = lockMap.get(key); if (lock == null) { lock = new Object(); lockMap.put(key, lock); } return lock; } } 仍外抱怨一下繁琐的代码风格 一个内部类,构造函数最多带n个参数,能后呢,某些人为了可能的使用方便,居然给配上了2的n次方个构造函数。晕啊,我真不想看你这么多的文档:( 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-02-25
感觉没有解决问题:2个线程如果同时请求相同的url,一个被堵住了,另外一个还是在那边等待锁吧?
|
|
返回顶楼 | |
发表时间:2009-02-25
最后修改:2009-02-25
恩,这个是的,但是如果这个url有问题,抓不下来,我们再开100个线程估计也是没用的了。
我只是解决了一个url有问题导致其他url死锁的bug。 QW有其他办法吗? |
|
返回顶楼 | |
发表时间:2009-02-25
jindw 写道 恩,这个是的,但是如果这个url有问题,抓不下来,我们再开100个线程估计也是没用的了。
我只是解决了一个url有问题导致其他url死锁的bug。 QW有其他办法吗? 没有想到好办法,不过parser.parse(url)这个方法里面没有处理超时吗?如果有超时设定的话,就不会一直堵了。 |
|
返回顶楼 | |
发表时间:2009-02-25
代码写的够烂的, 难道不会使用同步队列, 自己加个LOCK, 麻烦死了。
|
|
返回顶楼 | |
发表时间:2009-02-26
最后修改:2009-02-26
异常呢??
getFromCache不会抛出异常吗? synchronized里面抛出异常会释放锁的 |
|
返回顶楼 | |
发表时间:2009-02-26
最后修改:2009-02-26
为什么会导致装载延迟,如果url不存在的话,是不是用url直接返回null,或者马上抛出异常。是不是用到了URLConnection包,那为什么不把超时时间设置短一点
|
|
返回顶楼 | |
发表时间:2009-02-26
最后修改:2009-02-26
case0079 写道 异常呢??
getFromCache不会抛出异常吗? synchronized里面抛出异常会释放锁的 呵呵,我还真吧这个给忘了,低级错误^_^ 谢谢谢谢。 |
|
返回顶楼 | |
发表时间:2009-02-26
sdh5724 写道 代码写的够烂的, 难道不会使用同步队列, 自己加个LOCK, 麻烦死了。
能否详细一点呢? 我比较笨,呵呵 |
|
返回顶楼 | |