QQ机器人{线程应用篇}
来源:互联网 发布:mysqlsla windows 编辑:程序博客网 时间:2024/05/01 07:43
说实话,在写这个应用前,读过《Java并发编程的艺术》,但对于并发以及多线程的应用不是很多,现在写完后也算有了一定的了解,所以这篇文章就来聊聊项目中用到的一些线程框架。
如果对于流程不熟悉的还是先看下前面几篇文章吧,这里简单提一下线程应用的地方。
贴下代码吧,这样更直观。
package org.cool.qqrobot.thread;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import org.cool.qqrobot.common.Const;/** * 线程池(单例,将各种常用线程池封装在此类,方便统一调用) * @author zhoukl * */public final class ThreadPool { private static ThreadPool threadPool = new ThreadPool(); private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(Const.FIXED_THREAD_POOL_NUM); private static ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(Const.SCHEDULED_THREAD_POOL_NUM); private ThreadPool() {} public static ThreadPool getInstance() { return threadPool; } public ExecutorService getFixedThreadPool() { return fixedThreadPool; } public ScheduledExecutorService getScheduledThreadPool() { return scheduledThreadPool; }}
以上代码是定义的线程池,下面贴下具体应用。
第一处:二维码验证
服务端http请求获取到二维码后立即将二维码返回给了用户,异步线程开始轮询二维码的状态。
private void loginCheck(ProcessData processData) { logger.info("|{}|--二维码验证中", ProcessVar.getProcessId()); ThreadPool.getInstance().getFixedThreadPool().execute(new Runnable() { @Override public void run() { for (int i = 0; i < Const.CYCLE_NUM; i++) { MyHttpRequest checkRequest = new MyHttpRequest(); checkRequest.setUrl("https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1&login2qq=1&aid=501004106&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-9604&mibao_css=m_webqq&t=undefined&g=1&js_type=0&js_ver=10181&login_sig=&pt_randsalt=0"); MyHttpResponse checkResponse = new MyHttpResponse(); try { checkResponse = processData.getMyHttpClient().execute(checkRequest); } catch (Exception e) { processData.setGetCode(false); logger.error("二维码登录状态获取异常", e); } boolean firstLoginSuccess = false; if (MyHttpResponse.S_OK == checkResponse.getStatus()) { firstLoginSuccess = firstLogin(processData, checkResponse); } else { processData.setGetCode(false); } // 每次轮询休息一段时间,不然太频繁 threadSleep(); if (firstLoginSuccess) { break; } // 轮询时间结束,用户还未扫描登录,自动标识为登录失败(不然下次不能获取二维码,刷新页面二维码不变) if (i == Const.CYCLE_NUM - 1) { processData.setGetCode(false); } } } }); }
这里的轮询采用for循环控制,因为不需要永久轮询。部分方法未给出实现部分,但也没删是因为有涉及到过程数据(processData)的存取,之前只是提及,没有代码演示,现在贴出来可能会直观些。
第二处:用户登录信息记录
这部分没有实时同步需要,因此采用异步记录日志,线程池应用和上面一致。
// 异步记录登录用户信息// 登录成功后,记录当前登录日志的id,当用户主动退出时,再次更新登出时间ThreadPool.getInstance().getFixedThreadPool().execute(new Runnable() { @Override public void run() { logger.info("记录用户登录信息"); robotDao.addLoginInfo(userInfo); }});
IO读写担心耗时就采用异步线程。
第三处:消息轮询
用户的消息收发需要一直提供服务,所以线程不间断的轮询消息。
private void pollMessageThread(ProcessData processData) { logger.info("开始轮询消息"); // 把每一个轮询线程对象保存到map中,便于终止轮询(key:qq号,value:Future对象),同时清除登录成功的缓存信息,更新退出时间 Future<?> future = ThreadPool.getInstance().getScheduledThreadPool().scheduleAtFixedRate(new Runnable() { @Override public void run() { // 消息收发... } }, Const.INIT_DELAY, Const.PERIOD, TimeUnit.MICROSECONDS); // 保存当前线程future CacheMap.threadFuturMap.put(processData.getSelfUiu(), future); }
这里采用定时任务,循环执行服务的调用。此处还用到了map,因为是多线程并发操作,那么HashMap和HashTable显然都不合适了(至于为什么,其它文章有详细说明,这里就不重复了),所以采用ConcurrentHashMap保存缓存数据。
本来想聊聊多线程的原理什么的,看了下相关的书籍和博客,感觉自己的领悟程度还不够深,所以不敢妄加总结,大牛实在太多了,我等小辈还是多做多学多看吧。
好了,这个年也过的差不多了,又大一岁,好好努力,别辜负了时光~
1 0
- QQ机器人{线程应用篇}
- QQ机器人{应用设计篇}
- QQ机器人{协议篇}
- QQ聊天布局(聊天机器人应用)
- QQ机器人{功能介绍篇}
- QQ机器人{登录流程篇}
- QQ机器人
- QQ机器人
- QQ机器人{HTTP服务调用篇}
- 全自动QQ机器人|QQ机器人|宝宝智能QQ机器人
- QQ机器人(转贴)
- QQ机器人(转贴)
- QQ机器人的威力
- 免费QQ群机器人
- QQ 聊天机器人API
- perl qq 机器人
- 第五代QQ机器人
- QQ机器人插件
- 安装pyenv install时指定enable-shared
- 第13天(就业班) jsp内置对象、out对象、域对象、el表达式、jsp标签库
- [Leetcode] 14. Longest Common Prefix
- 从一个实例中学习DTW算法
- 在三位整数(100至999)中寻找符合条件的整数并依次从小到大存入数组中;他既是完全平方数,又是两位数字相同,例如144,676等
- QQ机器人{线程应用篇}
- quagga源码学习--BGP协议对等体连接tcp md5签名认证选项
- 深入了解R语言-S4
- 1072.Gas Station (30)
- jQuery--文档处理
- windows api创建定时器模板
- Java 基础入门知识1
- hduoj4826
- FOURIER ANALYSIS AN INTRODUCTION STEIN 第5章习题答案