11
异异异异异 MaYunLong

异步和队列分享

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: 异步和队列分享

异步和队列

MaYunLong

Page 2: 异步和队列分享

什么是异步编程• 异步模式:就是指程序中的一个线程执行到这个操作时,这个线程只是执行

一些必要的工作,启动这个操作后就继续执行后面的语句,不等待操作返回的结果。

• 同步模式:就是指当程序中的一个线程执行到这个操作时,这个线程就停滞在这里,直到这个操作执行完毕,线程才继续执行下一条语句。

Page 3: 异步和队列分享

异步适合的场景• 不需要马上返回结果的操作• 比较耗时的资源操作

– 文件的读写– 数据库读写– Cache 读写资源操作主要包括 I/O 操作和同步操作。而这些操作是应用中最耗时的操作,

也是应用的主要瓶颈所在。

Page 4: 异步和队列分享

如何进行异步编程• 启动子线程

– 把可以异步的操作,丢给其他线程(非主线程)处理。主线程可以继续做自己关注的 / 必须做的事(既用户需要看到的事)。

– 可以异步的操作:操作数据库、生成索引、广播给好友、通知后台审核等。

• 使用队列– 把可以异步的操作,放入到任务队列中;检测线程定时检查,发现任务

后,开辟线程,处理任务;线程处理完任务后,回收到线程池,等待分配下一个任务。

队列和子线程区别:子线程:主线程需负责开辟任务线程;分布任务等队列:主线程无需管理任务线程,只关注自己的事情即可

Page 5: 异步和队列分享
Page 6: 异步和队列分享

异步编程代码示例• /**• * 参加活动中奖 ===可通过配置增加• * @param baseEvent 动态基本信息( userId,relationId等)• * @param active 活动信息• * @param prize 中奖信息• * @throws Exception 操作 cache异常信息• */• public boolean activeHitPrize(FeedBaseEventModel baseEvent,• FeedVariantModel active, FeedVariantModel prize,String eventType)• throws Exception {

– // 组装 feed– FeedEventModel feedEvent=buildFeedModel(baseEvent, eventType, active,prize);– // 放入 " 生成动态队列 "– feedUpdateQuene.putElement(UpdateQueneConstant.QUENE_TYPE_FEED_GEN, feedEvent);

– return true;• }

Page 7: 异步和队列分享

队列类型• 阻塞队列

– 先进先出、固定大小;一旦创建了这样的缓存区,就不能再增加其容量。试图向已满队列中放入元素会导致放入操作受阻塞;试图从空队列中检索元素将导致类似阻塞。

– 当队列满时,会导致有些请求需延迟等待入队 – 特点:有界、会阻塞、入队需同步

• 无阻塞队列– 先进先出,无界;只要有入队请求,即可随时入队。– 有内存溢出的风险– 特点:无界、无阻塞、入队需同步

• 计数器队列– 通过维护一个计数器,来实现先进先出;数据可散列存储– 特点:无界、无阻塞、入队无需同步

Page 8: 异步和队列分享

计数器队列示意图

Page 9: 异步和队列分享

队列同步• 入队的任务为保证不丢失,一般需放在 cache( 最好可以在 cache 后

加 db)• 如果按普通的阻塞或无阻塞队列,在入队或出队时,都需要同步。• 计数器队列,只需按规则计算出 key 值,直接散列到 cache 即可。• 而计数器最大的优势就是入队时无需同步,而 cache 本身属于共享资

源,如果可以不同步直接操作,可以在性能上有很大的提升,而且是压力越大,性能越好。

• 那计数器队列就不许任何同步了吗?

Page 10: 异步和队列分享

队列计数器

• 计数器队列是通过维护“任务计数器”和“已处理任务计数器”来计算要处理的任务;

• 计数器为多线程共用,在计数时,需同步操作;但此同步为操作内存数据,对性能影响很少。

• 另外,如果用一个线程对计数器进行操作,也可去掉同步。

Page 11: 异步和队列分享

谢谢!