您当前的位置: 首页 >  Java

java持续实践

暂无认证

  • 3浏览

    0关注

    746博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Java多线程 活锁

java持续实践 发布时间:2020-09-13 11:21:36 ,浏览量:3

文章目录
      • 活性故障
      • 活锁 (Livelock)
      • 工程中的活锁实例: 消息队列

活性故障

死锁是最常见的活跃性问题, 除了死锁外, 还有类似的问题导致程序无法顺利的执行, 统称为活跃性问题. 例如 活锁 (Livelock) 饥饿

活锁 (Livelock)

什么是活锁 活锁具有两个特点, 第一个是线程没有阻塞, 始终在运行中(所以叫活锁, 线程是活的, 运行中的. ) 第二个特点: 程序却得不到进展, 因为线程始终重复同样的无效事情.

如下图 , 两个绅士弯腰, 如果是死锁, 那么就是两个人始终一动不动, 直到对方先抬头, 不再有对话, 只是等待.

如果是活锁, 双方都在不停的与对方说话, 是在运行中的, 在计算机中是消耗系统资源的.

死锁与活锁的结果是一样的, 谁都不能先抬头.

代码演示

只有在小于9的情况下, 才会把勺子给对方, 而大部分情况下是小于9的, random.nextInt(10) 获取的值的范围是0 到9 (包含9). 那么如果获取的是9 , 就不会让给对方, 自己就会先吃. 即百分之90的概率谦让 , 百分之10的概率不谦让.

工程中的活锁实例: 消息队列

工程中的活锁实例: 消息队列 消息队列如果处理失败, 会在catch的地方, 进行重试的策略, 假如把该消息放在队列的头中, 即每次重试的都是该失败的消息, 并且 该消息依赖的服务处了问题, 处理该消息就会一直失败, 那么就造成了活锁. 即没有进入阻塞状态, 但程序无法继续下去 .

解决办法 :

  1. 不把该发送失败的消息放在头中, 而是放入队列的末尾中, 这样即使发送失败了, 也不影响其他消息的发送.
  2. 限制重试的次数, 例如3 次, 5次 , 根据业务的不同设置重试的上限, 如果不限制重试的次数, 会消耗系统资源. 如果达到重试的次数还是没有发送成功后, 放入数据库中,数据库 如果有插入新的发送失败的消息后, 一方面触发报警机制, 另一方面, 把这些发送失败的消息, 有额外的定时任务去执行和重试, 这样就不会影响到主程序的运行.
关注
打赏
1658054974
查看更多评论
立即登录/注册

微信扫码登录

0.0901s