最近项目 某一功能遇到了一个小问题,经过朋友的帮助,我学会了使用synchronized方法,特此记录下来,以供交流学习。
具体问题:有一个号码设置的页面,在里面可以简单的输入号码和昵称,点击 保存按钮 数据会通过httpClient保存到服务器中。
我在保存的监听事件里遍历出 用户新创建的数据(post) 和 在原有基础上修改过的数据(put),各放在一个集合中, 接着判断集合的长度,有则请求服务器发送相应uri和post或put数据。
因为此功能的 添加 和 修改 是在一个 保存按钮里做的,所以如果当用户修改了数据,同时添加了一个数据,点击保存的时候,会同时new AsyncTask() 请求 httpclient连接,(我的httpClient工具类是直接全局new 一个httpclient 各方法用同一个clitent)
这样就会遇到问题:put(AsyncTask)正在执行中,接下来就会顺序执行到post(AsyncTask) 导致第一个put AsyncTask请求还在继续连接,第二个 post AsyncTask又次请求,通过AsyncTask引发了一个异常错误:
后来经过在httpclient测试,才发现是httpclient连接导致的错误,具体在post请求时作的这样处理:
在post请求时自己new 了一个新的DefaultHttpClient();再次运行就不会报错了,但是同事说这样做不好,因为一开始登录时那个httpclient保存在cookies里,在这里new 一个,会丢失一些登录状态,后台会说非法的。同时我因为使用了异步处理AsyncTask,这样做后虽然不出错误,但是每次同时修改后,只会保存post请求后的数据,put修改的数据没有得到httpclient的执行机会。
所以,最好的办法是使用同步代码块:
synchronized (mHttpClient){} 这个就是给httpclient加上锁,只需要简单的一句话就可以了,把需要执行的代码放在同步锁块里,如果其他(工具类post)方法也调用了httpclient,也加上之。
这样就可以保证在同一个时间段里,只有一个线程可以用到HttpClient,其他都阻塞了。只有当这个线程执行完毕后,他才会往下执行,简而言之,第二次post请求时,会一直卡在同步锁synchronized处,等到第一次put请求数据完毕后才会继续。这样就简单而完美解决了同时 修改 添加 的问题。
我的工具类:
保存按钮put处理代码: